hispano-lang 1.0.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.
- package/LICENSE +21 -0
- package/README.md +404 -0
- package/bin/hispano.js +313 -0
- package/dist/cli.d.ts +46 -0
- package/dist/evaluator.js +1391 -0
- package/dist/index.d.ts +185 -0
- package/dist/index.js +74 -0
- package/dist/interpreter.js +73 -0
- package/dist/parser.js +1050 -0
- package/dist/tokenizer.js +445 -0
- package/package.json +72 -0
package/bin/hispano.js
ADDED
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* HispanoLang CLI Tool
|
|
5
|
+
* Command-line interface for the HispanoLang interpreter
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const fs = require('fs');
|
|
9
|
+
const path = require('path');
|
|
10
|
+
const { interpret, run, getVariables, clearVariables, Interpreter } = require('../main.js');
|
|
11
|
+
|
|
12
|
+
// Colors for console output
|
|
13
|
+
const colors = {
|
|
14
|
+
green: '\x1b[32m',
|
|
15
|
+
red: '\x1b[31m',
|
|
16
|
+
yellow: '\x1b[33m',
|
|
17
|
+
blue: '\x1b[34m',
|
|
18
|
+
magenta: '\x1b[35m',
|
|
19
|
+
cyan: '\x1b[36m',
|
|
20
|
+
reset: '\x1b[0m',
|
|
21
|
+
bold: '\x1b[1m',
|
|
22
|
+
dim: '\x1b[2m'
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Display help information
|
|
27
|
+
*/
|
|
28
|
+
function showHelp() {
|
|
29
|
+
console.log(`
|
|
30
|
+
${colors.bold}${colors.cyan}HispanoLang - Intérprete de Lenguaje de Programación en Español${colors.reset}
|
|
31
|
+
|
|
32
|
+
${colors.bold}Uso:${colors.reset}
|
|
33
|
+
hispano [opciones] [archivo]
|
|
34
|
+
hispano-lang [opciones] [archivo]
|
|
35
|
+
|
|
36
|
+
${colors.bold}Opciones:${colors.reset}
|
|
37
|
+
-h, --help Mostrar esta ayuda
|
|
38
|
+
-v, --version Mostrar la versión
|
|
39
|
+
-i, --interactive Modo interactivo (REPL)
|
|
40
|
+
-e, --eval <código> Ejecutar código directamente
|
|
41
|
+
-t, --test Ejecutar tests
|
|
42
|
+
-d, --debug Modo debug (mostrar tokens y AST)
|
|
43
|
+
--no-color Desactivar colores en la salida
|
|
44
|
+
|
|
45
|
+
${colors.bold}Ejemplos:${colors.reset}
|
|
46
|
+
hispano # Modo interactivo
|
|
47
|
+
hispano script.hl # Ejecutar archivo
|
|
48
|
+
hispano -e "mostrar 'Hola'" # Ejecutar código
|
|
49
|
+
hispano --interactive # Modo interactivo
|
|
50
|
+
hispano --test # Ejecutar tests
|
|
51
|
+
|
|
52
|
+
${colors.bold}Archivos soportados:${colors.reset}
|
|
53
|
+
.hl, .hispano, .hispano-lang
|
|
54
|
+
|
|
55
|
+
${colors.bold}Documentación:${colors.reset}
|
|
56
|
+
https://github.com/nicvazquezdev/hispano-lang
|
|
57
|
+
`);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Display version information
|
|
62
|
+
*/
|
|
63
|
+
function showVersion() {
|
|
64
|
+
const packageJson = require('../package.json');
|
|
65
|
+
console.log(`${colors.bold}HispanoLang v${packageJson.version}${colors.reset}`);
|
|
66
|
+
console.log(`${colors.dim}${packageJson.description}${colors.reset}`);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Execute code with optional debug information
|
|
71
|
+
*/
|
|
72
|
+
function executeCode(code, options = {}) {
|
|
73
|
+
try {
|
|
74
|
+
if (options.debug) {
|
|
75
|
+
console.log(`${colors.yellow}🔍 Modo Debug Activado${colors.reset}\n`);
|
|
76
|
+
|
|
77
|
+
// Show tokens
|
|
78
|
+
const interpreter = new Interpreter();
|
|
79
|
+
const tokens = interpreter.tokenizer.tokenize(code);
|
|
80
|
+
console.log(`${colors.blue}📝 Tokens:${colors.reset}`);
|
|
81
|
+
tokens.forEach((token, index) => {
|
|
82
|
+
if (token.type !== 'EOF') {
|
|
83
|
+
console.log(` ${index}: ${token.type} "${token.lexeme}" (${token.literal})`);
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
console.log();
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const result = interpret(code);
|
|
90
|
+
|
|
91
|
+
if (result.success) {
|
|
92
|
+
if (result.output && result.output.length > 0) {
|
|
93
|
+
result.output.forEach(output => {
|
|
94
|
+
console.log(output);
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
} else {
|
|
98
|
+
console.error(`${colors.red}❌ Error: ${result.error}${colors.reset}`);
|
|
99
|
+
process.exit(1);
|
|
100
|
+
}
|
|
101
|
+
} catch (error) {
|
|
102
|
+
console.error(`${colors.red}❌ Error inesperado: ${error.message}${colors.reset}`);
|
|
103
|
+
process.exit(1);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Interactive REPL mode
|
|
109
|
+
*/
|
|
110
|
+
function startREPL() {
|
|
111
|
+
const readline = require('readline');
|
|
112
|
+
|
|
113
|
+
console.log(`${colors.bold}${colors.green}🚀 HispanoLang REPL${colors.reset}`);
|
|
114
|
+
console.log(`${colors.dim}Escribe código en español. Escribe 'salir' para terminar.${colors.reset}\n`);
|
|
115
|
+
|
|
116
|
+
const rl = readline.createInterface({
|
|
117
|
+
input: process.stdin,
|
|
118
|
+
output: process.stdout,
|
|
119
|
+
prompt: `${colors.cyan}hispano> ${colors.reset}`
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
rl.prompt();
|
|
123
|
+
|
|
124
|
+
rl.on('line', (input) => {
|
|
125
|
+
const trimmedInput = input.trim();
|
|
126
|
+
|
|
127
|
+
if (trimmedInput === 'salir' || trimmedInput === 'exit' || trimmedInput === 'quit') {
|
|
128
|
+
console.log(`${colors.green}¡Hasta luego! 👋${colors.reset}`);
|
|
129
|
+
rl.close();
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
if (trimmedInput === 'limpiar' || trimmedInput === 'clear') {
|
|
134
|
+
clearVariables();
|
|
135
|
+
console.log(`${colors.yellow}Variables limpiadas${colors.reset}`);
|
|
136
|
+
rl.prompt();
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
if (trimmedInput === 'variables' || trimmedInput === 'vars') {
|
|
141
|
+
const variables = getVariables();
|
|
142
|
+
if (Object.keys(variables).length === 0) {
|
|
143
|
+
console.log(`${colors.dim}No hay variables definidas${colors.reset}`);
|
|
144
|
+
} else {
|
|
145
|
+
console.log(`${colors.blue}Variables definidas:${colors.reset}`);
|
|
146
|
+
Object.entries(variables).forEach(([name, value]) => {
|
|
147
|
+
console.log(` ${name}: ${JSON.stringify(value)}`);
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
rl.prompt();
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
if (trimmedInput === 'ayuda' || trimmedInput === 'help') {
|
|
155
|
+
console.log(`${colors.blue}Comandos disponibles:${colors.reset}`);
|
|
156
|
+
console.log(` ${colors.cyan}salir${colors.reset} - Terminar el REPL`);
|
|
157
|
+
console.log(` ${colors.cyan}limpiar${colors.reset} - Limpiar variables`);
|
|
158
|
+
console.log(` ${colors.cyan}variables${colors.reset} - Mostrar variables definidas`);
|
|
159
|
+
console.log(` ${colors.cyan}ayuda${colors.reset} - Mostrar esta ayuda`);
|
|
160
|
+
rl.prompt();
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
if (trimmedInput === '') {
|
|
165
|
+
rl.prompt();
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
try {
|
|
170
|
+
executeCode(trimmedInput);
|
|
171
|
+
} catch (error) {
|
|
172
|
+
console.error(`${colors.red}❌ Error: ${error.message}${colors.reset}`);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
rl.prompt();
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
rl.on('close', () => {
|
|
179
|
+
process.exit(0);
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Run tests
|
|
185
|
+
*/
|
|
186
|
+
function runTests() {
|
|
187
|
+
console.log(`${colors.bold}${colors.yellow}🧪 Ejecutando Tests de HispanoLang${colors.reset}\n`);
|
|
188
|
+
|
|
189
|
+
try {
|
|
190
|
+
require('../test/test.js');
|
|
191
|
+
} catch (error) {
|
|
192
|
+
console.error(`${colors.red}❌ Error ejecutando tests: ${error.message}${colors.reset}`);
|
|
193
|
+
process.exit(1);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Read and execute file
|
|
199
|
+
*/
|
|
200
|
+
function executeFile(filePath) {
|
|
201
|
+
try {
|
|
202
|
+
const code = fs.readFileSync(filePath, 'utf8');
|
|
203
|
+
console.log(`${colors.blue}📄 Ejecutando: ${filePath}${colors.reset}\n`);
|
|
204
|
+
executeCode(code);
|
|
205
|
+
} catch (error) {
|
|
206
|
+
if (error.code === 'ENOENT') {
|
|
207
|
+
console.error(`${colors.red}❌ Archivo no encontrado: ${filePath}${colors.reset}`);
|
|
208
|
+
} else {
|
|
209
|
+
console.error(`${colors.red}❌ Error leyendo archivo: ${error.message}${colors.reset}`);
|
|
210
|
+
}
|
|
211
|
+
process.exit(1);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Main function
|
|
217
|
+
*/
|
|
218
|
+
function main() {
|
|
219
|
+
const args = process.argv.slice(2);
|
|
220
|
+
let options = {
|
|
221
|
+
debug: false,
|
|
222
|
+
noColor: false
|
|
223
|
+
};
|
|
224
|
+
|
|
225
|
+
// Parse arguments
|
|
226
|
+
for (let i = 0; i < args.length; i++) {
|
|
227
|
+
const arg = args[i];
|
|
228
|
+
|
|
229
|
+
switch (arg) {
|
|
230
|
+
case '-h':
|
|
231
|
+
case '--help':
|
|
232
|
+
showHelp();
|
|
233
|
+
process.exit(0);
|
|
234
|
+
break;
|
|
235
|
+
|
|
236
|
+
case '-v':
|
|
237
|
+
case '--version':
|
|
238
|
+
showVersion();
|
|
239
|
+
process.exit(0);
|
|
240
|
+
break;
|
|
241
|
+
|
|
242
|
+
case '-i':
|
|
243
|
+
case '--interactive':
|
|
244
|
+
startREPL();
|
|
245
|
+
return;
|
|
246
|
+
|
|
247
|
+
case '-e':
|
|
248
|
+
case '--eval':
|
|
249
|
+
if (i + 1 < args.length) {
|
|
250
|
+
const code = args[i + 1];
|
|
251
|
+
executeCode(code, options);
|
|
252
|
+
process.exit(0);
|
|
253
|
+
} else {
|
|
254
|
+
console.error(`${colors.red}❌ Error: --eval requiere código${colors.reset}`);
|
|
255
|
+
process.exit(1);
|
|
256
|
+
}
|
|
257
|
+
break;
|
|
258
|
+
|
|
259
|
+
case '-t':
|
|
260
|
+
case '--test':
|
|
261
|
+
runTests();
|
|
262
|
+
process.exit(0);
|
|
263
|
+
break;
|
|
264
|
+
|
|
265
|
+
case '-d':
|
|
266
|
+
case '--debug':
|
|
267
|
+
options.debug = true;
|
|
268
|
+
break;
|
|
269
|
+
|
|
270
|
+
case '--no-color':
|
|
271
|
+
options.noColor = true;
|
|
272
|
+
// Disable colors
|
|
273
|
+
Object.keys(colors).forEach(key => {
|
|
274
|
+
colors[key] = '';
|
|
275
|
+
});
|
|
276
|
+
break;
|
|
277
|
+
|
|
278
|
+
default:
|
|
279
|
+
// Check if it's a file
|
|
280
|
+
if (!arg.startsWith('-')) {
|
|
281
|
+
const filePath = path.resolve(arg);
|
|
282
|
+
const ext = path.extname(filePath);
|
|
283
|
+
|
|
284
|
+
// Check if it's a supported file
|
|
285
|
+
if (['.hl', '.hispano', '.hispano-lang', '.js'].includes(ext) ||
|
|
286
|
+
fs.existsSync(filePath)) {
|
|
287
|
+
executeFile(filePath);
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
break;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
// If no arguments, start interactive mode
|
|
296
|
+
if (args.length === 0) {
|
|
297
|
+
startREPL();
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
// Run main function
|
|
302
|
+
if (require.main === module) {
|
|
303
|
+
main();
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
module.exports = {
|
|
307
|
+
executeCode,
|
|
308
|
+
startREPL,
|
|
309
|
+
runTests,
|
|
310
|
+
executeFile,
|
|
311
|
+
showHelp,
|
|
312
|
+
showVersion
|
|
313
|
+
};
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HispanoLang CLI - TypeScript Definitions
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Opciones para ejecutar código
|
|
7
|
+
*/
|
|
8
|
+
export interface ExecuteOptions {
|
|
9
|
+
/** Activar modo debug */
|
|
10
|
+
debug?: boolean;
|
|
11
|
+
/** Desactivar colores */
|
|
12
|
+
noColor?: boolean;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Ejecuta código con opciones opcionales
|
|
17
|
+
* @param code - Código a ejecutar
|
|
18
|
+
* @param options - Opciones de ejecución
|
|
19
|
+
*/
|
|
20
|
+
export function executeCode(code: string, options?: ExecuteOptions): void;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Inicia el modo REPL interactivo
|
|
24
|
+
*/
|
|
25
|
+
export function startREPL(): void;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Ejecuta los tests
|
|
29
|
+
*/
|
|
30
|
+
export function runTests(): void;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Ejecuta un archivo
|
|
34
|
+
* @param filePath - Ruta del archivo
|
|
35
|
+
*/
|
|
36
|
+
export function executeFile(filePath: string): void;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Muestra la ayuda
|
|
40
|
+
*/
|
|
41
|
+
export function showHelp(): void;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Muestra la versión
|
|
45
|
+
*/
|
|
46
|
+
export function showVersion(): void;
|