darijacode 0.2.0

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,90 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = statementGen;
4
+ const errors_1 = require("../errors");
5
+ function statementGen(codegen, stmt, scope) {
6
+ switch (stmt.type) {
7
+ case "VariableDeclaration": {
8
+ if (!stmt.init) {
9
+ throw new errors_1.CodegenError(`'${stmt.name}' khas t3ta liha 9ima`, stmt.pos.line, stmt.pos.column);
10
+ }
11
+ const type = stmt.typeAnnotation ?? codegen.inferType(stmt.init, scope);
12
+ scope.declare(stmt.name, type);
13
+ if (!type.d && stmt.init.type === "ArrayExpression") {
14
+ const values = stmt.init.elements.map((e) => codegen.genExpression(e, scope));
15
+ codegen.emit(`${codegen.cType(type)} ${stmt.name}[] = {${values.join(", ")}};`);
16
+ }
17
+ else {
18
+ codegen.emit(`${codegen.cType(type)} ${stmt.name} = ${codegen.genExpression(stmt.init, scope)};`);
19
+ }
20
+ return;
21
+ }
22
+ case "FunctionDeclaration":
23
+ // handled at the top level; nested function declarations aren't supported yet
24
+ throw new errors_1.CodegenError("ddawal lmtad5lin mmd3ominch l7ad sa3a", stmt.pos.line, stmt.pos.column);
25
+ case "ReturnStatement":
26
+ codegen.emit(stmt.argument ? `return ${codegen.genExpression(stmt.argument, scope)};` : "return;");
27
+ return;
28
+ case "IfStatement": {
29
+ codegen.emit(`if (${codegen.genExpression(stmt.condition, scope)}) {`);
30
+ codegen.genNestedBlock(stmt.consequent, scope);
31
+ for (const branch of stmt.elseIfs) {
32
+ codegen.emit(`} else if (${codegen.genExpression(branch.condition, scope)}) {`);
33
+ codegen.genNestedBlock(branch.consequent, scope);
34
+ }
35
+ if (stmt.alternate) {
36
+ codegen.emit(`} else {`);
37
+ codegen.genNestedBlock(stmt.alternate, scope);
38
+ }
39
+ codegen.emit(`}`);
40
+ return;
41
+ }
42
+ case "WhileStatement":
43
+ codegen.emit(`while (${codegen.genExpression(stmt.condition, scope)}) {`);
44
+ codegen.genNestedBlock(stmt.body, scope);
45
+ codegen.emit(`}`);
46
+ return;
47
+ case "ForStatement": {
48
+ const forScope = scope.child();
49
+ let initStr = "";
50
+ if (stmt.init?.type === "VariableDeclaration") {
51
+ if (!stmt.init.init) {
52
+ throw new errors_1.CodegenError(`'${stmt.init.name}' khas t3ta liha 9ima`, stmt.pos.line, stmt.pos.column);
53
+ }
54
+ const type = stmt.init.typeAnnotation ?? codegen.inferType(stmt.init.init, forScope);
55
+ forScope.declare(stmt.init.name, type);
56
+ initStr = `${codegen.cType(type)} ${stmt.init.name} = ${codegen.genExpression(stmt.init.init, forScope)}`;
57
+ }
58
+ else if (stmt.init?.type === "ExpressionStatement") {
59
+ initStr = codegen.genExpression(stmt.init.expression, forScope);
60
+ }
61
+ const condStr = stmt.condition ? codegen.genExpression(stmt.condition, forScope) : "";
62
+ const updateStr = stmt.update ? codegen.genExpression(stmt.update, forScope) : "";
63
+ codegen.emit(`for (${initStr}; ${condStr}; ${updateStr}) {`);
64
+ codegen.genNestedBlock(stmt.body, forScope);
65
+ codegen.emit(`}`);
66
+ return;
67
+ }
68
+ case "BreakStatement":
69
+ codegen.emit("break;");
70
+ return;
71
+ case "ContinueStatement":
72
+ codegen.emit("continue;");
73
+ return;
74
+ case "BlockStatement":
75
+ codegen.emit("{");
76
+ codegen.genNestedBlock(stmt, scope);
77
+ codegen.emit("}");
78
+ return;
79
+ case "PrintStatement": {
80
+ const type = codegen.inferType(stmt.argument, scope);
81
+ codegen.emit(codegen.genPrint(stmt.argument, type, scope));
82
+ return;
83
+ }
84
+ case "ExpressionStatement":
85
+ codegen.emit(`${codegen.genExpression(stmt.expression, scope)};`);
86
+ return;
87
+ default:
88
+ throw new errors_1.CodegenError(`'${stmt.type}' ba9i mmd3omach`, stmt.pos.line, stmt.pos.column);
89
+ }
90
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,115 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.compile = compile;
37
+ exports.checkOnly = checkOnly;
38
+ const child_process_1 = require("child_process");
39
+ const fs = __importStar(require("fs"));
40
+ const os = __importStar(require("os"));
41
+ const path = __importStar(require("path"));
42
+ const lexer_1 = require("./lexer");
43
+ const parser_1 = require("./parser");
44
+ const index_1 = require("./checker/index");
45
+ const codegen_1 = require("./codegen/codegen");
46
+ const errors_1 = require("./errors");
47
+ function compile(sourcePath, options = {}) {
48
+ const source = fs.readFileSync(sourcePath, "utf8");
49
+ const tokens = new lexer_1.Lexer(source).tokenize();
50
+ const ast = new parser_1.Parser(tokens).parse();
51
+ new index_1.Checker().check(ast);
52
+ const cSource = new codegen_1.Codegen().generate(ast);
53
+ const outputPath = options.outputPath ?? defaultOutputPath(sourcePath);
54
+ const cFile = writeCFile(sourcePath, outputPath, cSource, options.keepCFile ?? false);
55
+ try {
56
+ compileCFile(cFile, outputPath, options.cc);
57
+ }
58
+ finally {
59
+ if (!options.keepCFile) {
60
+ fs.rmSync(cFile, { force: true });
61
+ }
62
+ }
63
+ return {
64
+ binaryPath: outputPath,
65
+ cFilePath: options.keepCFile ? cFile : null
66
+ };
67
+ }
68
+ function checkOnly(sourcePath) {
69
+ const source = fs.readFileSync(sourcePath, "utf8");
70
+ const tokens = new lexer_1.Lexer(source).tokenize();
71
+ const ast = new parser_1.Parser(tokens).parse();
72
+ new index_1.Checker().check(ast);
73
+ }
74
+ function defaultOutputPath(sourcePath) {
75
+ const dir = path.dirname(sourcePath);
76
+ const name = path.basename(sourcePath, path.extname(sourcePath));
77
+ return path.join(dir, name);
78
+ }
79
+ function writeCFile(sourcePath, outputPath, code, keep) {
80
+ const cFile = keep
81
+ ? `${outputPath}.c`
82
+ : path.join(os.tmpdir(), `${path.basename(sourcePath)}-${Date.now()}.c`);
83
+ fs.writeFileSync(cFile, code);
84
+ return cFile;
85
+ }
86
+ function compileCFile(cFile, output, preferred) {
87
+ const compilers = preferred
88
+ ? [preferred]
89
+ : ["clang", "gcc"];
90
+ let last;
91
+ for (const cc of compilers) {
92
+ try {
93
+ (0, child_process_1.execFileSync)(cc, [cFile, "-lm", "-o", output], { stdio: "pipe" });
94
+ return;
95
+ }
96
+ catch (err) {
97
+ last = err;
98
+ }
99
+ }
100
+ const stderr = last &&
101
+ typeof last === "object" &&
102
+ "stderr" in last
103
+ ? String(last.stderr)
104
+ : String(last);
105
+ throw new errors_1.DarijaError({
106
+ code: "DCE-1",
107
+ stage: "codegen",
108
+ message: "C compiler failed.",
109
+ location: {
110
+ line: 0,
111
+ column: 0
112
+ },
113
+ hint: stderr
114
+ });
115
+ }
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DarijaError = exports.CodegenError = void 0;
4
+ exports.printDarijaError = printDarijaError;
5
+ class CodegenError extends Error {
6
+ constructor(message, line = -1, column = -1) {
7
+ super();
8
+ throw new DarijaError({
9
+ code: "DCE-0",
10
+ stage: "codegen",
11
+ message: `DarijaCode Codegen Error: ${message} at ${line}:${column}`,
12
+ location: {
13
+ line: line,
14
+ column: column
15
+ }
16
+ });
17
+ }
18
+ }
19
+ exports.CodegenError = CodegenError;
20
+ class DarijaError extends Error {
21
+ stage;
22
+ code;
23
+ location;
24
+ hint;
25
+ constructor(options) {
26
+ super(options.message);
27
+ this.name = "DarijaError";
28
+ this.stage = options.stage;
29
+ this.code = options.code;
30
+ this.location = options.location;
31
+ this.hint = options.hint;
32
+ }
33
+ }
34
+ exports.DarijaError = DarijaError;
35
+ const colors = {
36
+ red: "\x1b[31m",
37
+ yellow: "\x1b[33m",
38
+ blue: "\x1b[36m",
39
+ gray: "\x1b[90m",
40
+ reset: "\x1b[0m",
41
+ };
42
+ function printDarijaError(err, file, source) {
43
+ const { stage, code, location, message, hint } = err;
44
+ console.error(`${colors.red}DarijaCode error${colors.reset}[${colors.gray}${stage}:${code}${colors.reset}] ${message}`);
45
+ console.error(`${colors.gray}-->${colors.reset} ${file}:${location.line}:${location.column}`);
46
+ if (source) {
47
+ const lines = source.split("\n");
48
+ const line = lines[location.line - 1];
49
+ if (line) {
50
+ console.error(`${colors.blue}${location.line} |${colors.reset} ${line}`);
51
+ console.error(`${colors.blue} |${colors.reset} ` +
52
+ " ".repeat(location.column - 1) +
53
+ `${colors.red}^${colors.reset}`);
54
+ }
55
+ }
56
+ if (hint) {
57
+ console.error(`${colors.yellow}jrb/chof${colors.reset}: ${hint}`);
58
+ }
59
+ }
@@ -0,0 +1,69 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.compile = void 0;
37
+ exports.default = execute;
38
+ const fs = __importStar(require("fs"));
39
+ const child_process_1 = require("child_process");
40
+ const compiler_1 = require("./compiler");
41
+ Object.defineProperty(exports, "compile", { enumerable: true, get: function () { return compiler_1.compile; } });
42
+ const errors_1 = require("./errors");
43
+ function execute(option, file) {
44
+ switch (option) {
45
+ case "check":
46
+ (0, compiler_1.checkOnly)(file);
47
+ break;
48
+ case "build":
49
+ compileItForMe(file);
50
+ break;
51
+ case "run": {
52
+ const binpath = compileItForMe(file);
53
+ (0, child_process_1.execFileSync)(binpath.binaryPath, { stdio: "inherit" });
54
+ }
55
+ }
56
+ }
57
+ function compileItForMe(file) {
58
+ try {
59
+ return (0, compiler_1.compile)(file);
60
+ }
61
+ catch (err) {
62
+ if (err instanceof errors_1.DarijaError) {
63
+ const source = fs.readFileSync(file, "utf-8");
64
+ (0, errors_1.printDarijaError)(err, file, source);
65
+ process.exit(1);
66
+ }
67
+ throw err;
68
+ }
69
+ }
@@ -0,0 +1,303 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Lexer = void 0;
4
+ const tokens_1 = require("./tokens");
5
+ const errors_1 = require("./errors");
6
+ const keywords = {
7
+ dir: tokens_1.TokenType.DIR,
8
+ khli: tokens_1.TokenType.KHLI,
9
+ kteb: tokens_1.TokenType.KTEB,
10
+ dalla: tokens_1.TokenType.FN,
11
+ raj3: tokens_1.TokenType.RAJ3,
12
+ ila: tokens_1.TokenType.ILA,
13
+ awla: tokens_1.TokenType.AWLA,
14
+ wla: tokens_1.TokenType.WLA,
15
+ mahd: tokens_1.TokenType.MAHD,
16
+ dwr: tokens_1.TokenType.DWR,
17
+ qta3: tokens_1.TokenType.QTA3,
18
+ kml: tokens_1.TokenType.KAML,
19
+ class: tokens_1.TokenType.CLASS,
20
+ lbnnay: tokens_1.TokenType.DIRFLBLASA,
21
+ wratmn: tokens_1.TokenType.WRAATMN,
22
+ sa7i7: tokens_1.TokenType.TRUE,
23
+ ghalat: tokens_1.TokenType.FALSE,
24
+ khawi: tokens_1.TokenType.NULL,
25
+ };
26
+ class Lexer {
27
+ source;
28
+ tokens = [];
29
+ cursor = 0;
30
+ line = 1;
31
+ column = 1;
32
+ constructor(source) {
33
+ this.source = source;
34
+ }
35
+ tokenize() {
36
+ while (!this.isEnd()) {
37
+ const startLine = this.line;
38
+ const startColumn = this.column;
39
+ const char = this.peek();
40
+ if (char === " " || char === "\t" || char === "\r") {
41
+ this.advance();
42
+ continue;
43
+ }
44
+ if (char === "\n") {
45
+ this.advance();
46
+ this.add(tokens_1.TokenType.NEWLINE, "\\n", startLine, startColumn);
47
+ continue;
48
+ }
49
+ if (char === "/" && this.peek(1) === "/") {
50
+ while (!this.isEnd() && this.peek() !== "\n") {
51
+ this.advance();
52
+ }
53
+ continue;
54
+ }
55
+ if (char === "/" && this.peek(1) === "*") {
56
+ this.advance();
57
+ this.advance();
58
+ while (!this.isEnd() &&
59
+ !(this.peek() === "*" && this.peek(1) === "/")) {
60
+ this.advance();
61
+ }
62
+ this.advance();
63
+ this.advance();
64
+ continue;
65
+ }
66
+ if (char === '"' || char === "'") {
67
+ this.readString(char);
68
+ continue;
69
+ }
70
+ if (this.isDigit(char)) {
71
+ this.readNumber();
72
+ continue;
73
+ }
74
+ if (this.isIdentifierStart(char)) {
75
+ this.readIdentifier();
76
+ continue;
77
+ }
78
+ switch (char) {
79
+ case "(":
80
+ this.simple(tokens_1.TokenType.LPAREN);
81
+ break;
82
+ case ")":
83
+ this.simple(tokens_1.TokenType.RPAREN);
84
+ break;
85
+ case "{":
86
+ this.simple(tokens_1.TokenType.LBRACE);
87
+ break;
88
+ case "}":
89
+ this.simple(tokens_1.TokenType.RBRACE);
90
+ break;
91
+ case "[":
92
+ this.simple(tokens_1.TokenType.LBRACT);
93
+ break;
94
+ case "]":
95
+ this.simple(tokens_1.TokenType.RBRACT);
96
+ break;
97
+ case "+":
98
+ if (this.match("+"))
99
+ this.simple(tokens_1.TokenType.PLUSPLUS, "++");
100
+ else
101
+ this.simple(tokens_1.TokenType.PLUS);
102
+ break;
103
+ case "-":
104
+ if (this.match("-"))
105
+ this.simple(tokens_1.TokenType.MINUSMINUS, "--");
106
+ else
107
+ this.simple(tokens_1.TokenType.MINUS);
108
+ break;
109
+ case "*":
110
+ if (this.match("*"))
111
+ this.simple(tokens_1.TokenType.POWER, "**");
112
+ else
113
+ this.simple(tokens_1.TokenType.STAR);
114
+ break;
115
+ case "/":
116
+ this.simple(tokens_1.TokenType.SLASH);
117
+ break;
118
+ case "%":
119
+ this.simple(tokens_1.TokenType.PERCENT);
120
+ break;
121
+ case "=":
122
+ if (this.match("="))
123
+ this.simple(tokens_1.TokenType.EQEQ, "==");
124
+ else
125
+ this.simple(tokens_1.TokenType.EQUAL);
126
+ break;
127
+ case ":":
128
+ if (this.match("="))
129
+ this.simple(tokens_1.TokenType.COLONEQUAL, ":=");
130
+ else
131
+ this.simple(tokens_1.TokenType.COLON);
132
+ break;
133
+ case "!":
134
+ if (this.match("="))
135
+ this.simple(tokens_1.TokenType.NOTEQ, "!=");
136
+ else
137
+ this.simple(tokens_1.TokenType.NOT);
138
+ break;
139
+ case "<":
140
+ if (this.match("="))
141
+ this.simple(tokens_1.TokenType.LTEQ, "<=");
142
+ else
143
+ this.simple(tokens_1.TokenType.LT);
144
+ break;
145
+ case ">":
146
+ if (this.match("="))
147
+ this.simple(tokens_1.TokenType.GTEQ, ">=");
148
+ else
149
+ this.simple(tokens_1.TokenType.GT);
150
+ break;
151
+ case "&":
152
+ if (this.match("&"))
153
+ this.simple(tokens_1.TokenType.AND, "&&");
154
+ else
155
+ this.error("twa93na &&", "DCE12");
156
+ break;
157
+ case "|":
158
+ if (this.match("|"))
159
+ this.simple(tokens_1.TokenType.OR, "||");
160
+ else
161
+ this.error("twa93na ||", "DCE12");
162
+ break;
163
+ case ".":
164
+ this.simple(tokens_1.TokenType.DOT);
165
+ break;
166
+ case ",":
167
+ this.simple(tokens_1.TokenType.COMMA);
168
+ break;
169
+ case "?":
170
+ this.simple(tokens_1.TokenType.QUESTION);
171
+ break;
172
+ case ";":
173
+ this.simple(tokens_1.TokenType.EOS);
174
+ break;
175
+ default:
176
+ this.error(`7arf mam3rofch '${char}'`, "DCE1");
177
+ }
178
+ }
179
+ this.tokens.push({
180
+ type: tokens_1.TokenType.EOF,
181
+ value: "",
182
+ line: this.line,
183
+ column: this.column,
184
+ });
185
+ return this.tokens;
186
+ }
187
+ readIdentifier() {
188
+ const line = this.line;
189
+ const column = this.column;
190
+ let value = "";
191
+ while (this.isIdentifierPart(this.peek())) {
192
+ value += this.advance();
193
+ }
194
+ const type = keywords[value] ?? tokens_1.TokenType.IDENTF;
195
+ this.add(type, value, line, column);
196
+ }
197
+ readNumber() {
198
+ const line = this.line;
199
+ const column = this.column;
200
+ let value = "";
201
+ while (this.isDigit(this.peek()) || this.peek() === "_") {
202
+ value += this.advance();
203
+ }
204
+ if (this.peek() === "." && this.isDigit(this.peek(1))) {
205
+ value += this.advance();
206
+ while (this.isDigit(this.peek())) {
207
+ value += this.advance();
208
+ }
209
+ }
210
+ this.add(tokens_1.TokenType.NUMBER, value.replaceAll("_", ""), line, column);
211
+ }
212
+ readString(quote) {
213
+ const start = {
214
+ line: this.line,
215
+ column: this.column
216
+ };
217
+ this.advance();
218
+ let value = "";
219
+ while (!this.isEnd() && this.peek() !== quote) {
220
+ const char = this.advance();
221
+ if (char === "\\") {
222
+ const next = this.advance();
223
+ switch (next) {
224
+ case "n":
225
+ value += "\n";
226
+ break;
227
+ case "t":
228
+ value += "\t";
229
+ break;
230
+ default:
231
+ value += next;
232
+ }
233
+ }
234
+ else {
235
+ value += char;
236
+ }
237
+ }
238
+ if (this.isEnd()) {
239
+ this.error("nass mamkmolch", "DCE11", "bhal haka -> \"wafin, al3alam !\"", start);
240
+ }
241
+ this.advance();
242
+ this.add(tokens_1.TokenType.STRING, value, start.line, start.column);
243
+ }
244
+ simple(type, value) {
245
+ const line = this.line;
246
+ const column = this.column;
247
+ const char = this.advance();
248
+ this.add(type, value ?? char, line, column);
249
+ }
250
+ match(expected) {
251
+ if (this.peek(1) !== expected)
252
+ return false;
253
+ this.advance();
254
+ return true;
255
+ }
256
+ add(type, value, line, column) {
257
+ this.tokens.push({
258
+ type,
259
+ value,
260
+ line,
261
+ column,
262
+ });
263
+ }
264
+ advance() {
265
+ const char = this.source[this.cursor++];
266
+ if (char === "\n") {
267
+ this.line++;
268
+ this.column = 1;
269
+ }
270
+ else {
271
+ this.column++;
272
+ }
273
+ return char;
274
+ }
275
+ peek(offset = 0) {
276
+ return this.source[this.cursor + offset] ?? "\0";
277
+ }
278
+ isEnd() {
279
+ return this.cursor >= this.source.length;
280
+ }
281
+ isDigit(c) {
282
+ return c >= "0" && c <= "9";
283
+ }
284
+ isIdentifierStart(c) {
285
+ return /[a-zA-Z_]/.test(c);
286
+ }
287
+ isIdentifierPart(c) {
288
+ return /[a-zA-Z0-9_]/.test(c);
289
+ }
290
+ error(message, ecode, hint, location = {
291
+ line: this.line,
292
+ column: this.column
293
+ }) {
294
+ throw new errors_1.DarijaError({
295
+ code: ecode,
296
+ stage: "lexer",
297
+ message,
298
+ location,
299
+ hint: hint ?? ""
300
+ });
301
+ }
302
+ }
303
+ exports.Lexer = Lexer;