raizcode-ofc 1.8.0 → 1.9.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/compilador.js +296 -86
- package/exemplos/teste.js +6 -0
- package/exemplos/teste.rc +5 -0
- package/package.json +11 -37
package/compilador.js
CHANGED
|
@@ -3,101 +3,250 @@
|
|
|
3
3
|
const fs = require('fs');
|
|
4
4
|
const path = require('path');
|
|
5
5
|
const os = require('os');
|
|
6
|
-
const http = require('http');
|
|
6
|
+
const http = require('http');
|
|
7
7
|
const { execSync, exec } = require('child_process');
|
|
8
8
|
|
|
9
9
|
const args = process.argv.slice(2);
|
|
10
10
|
const arquivoOuCmd = args[0];
|
|
11
11
|
|
|
12
|
-
//
|
|
12
|
+
// ─────────────────────────────────────────
|
|
13
|
+
// SETUP DO VSCODE
|
|
14
|
+
// ─────────────────────────────────────────
|
|
13
15
|
if (arquivoOuCmd === '--setup') {
|
|
14
16
|
const extDir = path.join(os.homedir(), '.vscode', 'extensions', 'raizcode-extension');
|
|
15
17
|
try {
|
|
16
18
|
if (!fs.existsSync(extDir)) fs.mkdirSync(extDir, { recursive: true });
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
19
|
+
|
|
20
|
+
// Copia arquivos necessários
|
|
21
|
+
['syntaxes', 'icons'].forEach(pasta => {
|
|
22
|
+
const src = path.join(__dirname, pasta);
|
|
23
|
+
const dest = path.join(extDir, pasta);
|
|
20
24
|
if (fs.existsSync(src)) {
|
|
21
|
-
|
|
22
|
-
else fs.copyFileSync(src, dest);
|
|
25
|
+
fs.cpSync(src, dest, { recursive: true });
|
|
23
26
|
}
|
|
24
27
|
});
|
|
25
|
-
|
|
26
|
-
|
|
28
|
+
|
|
29
|
+
// Gera o package.json da extensão VSCode corretamente
|
|
30
|
+
const pkgExtensao = {
|
|
31
|
+
name: "raizcode-extension",
|
|
32
|
+
displayName: "Raizcode",
|
|
33
|
+
version: "1.8.0",
|
|
34
|
+
publisher: "raizcode",
|
|
35
|
+
engines: { vscode: "^1.60.0" },
|
|
36
|
+
contributes: {
|
|
37
|
+
languages: [
|
|
38
|
+
{
|
|
39
|
+
id: "raizcode",
|
|
40
|
+
aliases: ["Raizcode", "rc"],
|
|
41
|
+
extensions: [".rc"],
|
|
42
|
+
icon: { dark: "./icons/rc.png", light: "./icons/rc.png" }
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
id: "raizcode-estrutura",
|
|
46
|
+
aliases: ["Raizcode Estrutura", "rcx"],
|
|
47
|
+
extensions: [".rcx"],
|
|
48
|
+
icon: { dark: "./icons/rcx.png", light: "./icons/rcx.png" }
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
id: "raizcode-estilo",
|
|
52
|
+
aliases: ["Raizcode Estilo", "rcc"],
|
|
53
|
+
extensions: [".rcc"],
|
|
54
|
+
icon: { dark: "./icons/rcc.png", light: "./icons/rcc.png" }
|
|
55
|
+
}
|
|
56
|
+
],
|
|
57
|
+
grammars: [
|
|
58
|
+
{
|
|
59
|
+
language: "raizcode",
|
|
60
|
+
scopeName: "source.rc",
|
|
61
|
+
path: "./syntaxes/raizcode.tmLanguage.json"
|
|
62
|
+
}
|
|
63
|
+
]
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
fs.writeFileSync(
|
|
68
|
+
path.join(extDir, 'package.json'),
|
|
69
|
+
JSON.stringify(pkgExtensao, null, 2)
|
|
70
|
+
);
|
|
71
|
+
|
|
72
|
+
console.log("✅ Extensão Raizcode instalada! Reinicie o VS Code.");
|
|
73
|
+
console.log(`📁 Local: ${extDir}`);
|
|
74
|
+
} catch (e) {
|
|
75
|
+
console.error("❌ Erro no setup:", e.message);
|
|
76
|
+
}
|
|
27
77
|
process.exit();
|
|
28
78
|
}
|
|
29
79
|
|
|
30
|
-
//
|
|
31
|
-
|
|
80
|
+
// ─────────────────────────────────────────
|
|
81
|
+
// UTILITÁRIOS
|
|
82
|
+
// ─────────────────────────────────────────
|
|
32
83
|
|
|
33
|
-
//
|
|
84
|
+
// Abre o navegador de forma correta em qualquer sistema
|
|
85
|
+
function abrirNavegador(url) {
|
|
86
|
+
const plataforma = os.platform();
|
|
87
|
+
if (plataforma === 'win32') exec(`start ${url}`);
|
|
88
|
+
else if (plataforma === 'darwin') exec(`open ${url}`);
|
|
89
|
+
else if (process.env.TERM === 'xterm-termux' || fs.existsSync('/data/data/com.termux')) exec(`termux-open ${url}`);
|
|
90
|
+
else exec(`xdg-open ${url}`);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Reporta erros com número de linha para o usuário
|
|
94
|
+
function erroDeCompilacao(mensagem, numeroLinha) {
|
|
95
|
+
console.error(`\n❌ Erro na linha ${numeroLinha}: ${mensagem}`);
|
|
96
|
+
console.error(` Verifique seu código .rc e tente novamente.\n`);
|
|
97
|
+
process.exit(1);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// ─────────────────────────────────────────
|
|
101
|
+
// TRADUTORES DE ESTRUTURA (RCX) E ESTILO (RCC)
|
|
102
|
+
// ─────────────────────────────────────────
|
|
34
103
|
|
|
35
104
|
function traduzirEstrutura(conteudo) {
|
|
36
|
-
if(!conteudo) return "";
|
|
37
|
-
|
|
105
|
+
if (!conteudo) return "";
|
|
106
|
+
|
|
107
|
+
return conteudo.split('\n').map((linha, idx) => {
|
|
38
108
|
let t = linha.trim();
|
|
39
|
-
if(!t) return "";
|
|
40
|
-
|
|
41
|
-
|
|
109
|
+
if (!t || t.startsWith('//')) return "";
|
|
110
|
+
|
|
111
|
+
// Captura string entre aspas de forma segura
|
|
112
|
+
const pegarTexto = (cmd) => {
|
|
113
|
+
const match = t.match(new RegExp(`^${cmd}\\s+"(.*)"`));
|
|
114
|
+
return match ? match[1] : t.replace(cmd + ' ', '').replace(/"/g, '');
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
if (t.startsWith('titulo ')) return `<h1>${pegarTexto('titulo')}</h1>`;
|
|
118
|
+
if (t.startsWith('subtitulo ')) return `<h2>${pegarTexto('subtitulo')}</h2>`;
|
|
119
|
+
if (t.startsWith('texto ')) return `<p>${pegarTexto('texto')}</p>`;
|
|
120
|
+
if (t.startsWith('link ')) {
|
|
121
|
+
// link "Clique aqui" url "https://..."
|
|
122
|
+
const m = t.match(/^link\s+"(.+?)"\s+url\s+"(.+?)"/);
|
|
123
|
+
if (m) return `<a href="${m[2]}" target="_blank">${m[1]}</a>`;
|
|
124
|
+
}
|
|
125
|
+
if (t.startsWith('imagem ')) return `<img src="${pegarTexto('imagem')}" alt="imagem" style="max-width:100%;">`;
|
|
42
126
|
if (t.startsWith('botao ')) {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
return `<button id="${id}">${texto}</button>`;
|
|
127
|
+
const m = t.match(/^botao\s+"(.+?)"\s+id\s+"(.+?)"/);
|
|
128
|
+
if (m) return `<button id="${m[2]}">${m[1]}</button>`;
|
|
129
|
+
return `<button>${pegarTexto('botao')}</button>`;
|
|
47
130
|
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
131
|
+
if (t.startsWith('entrada ')) {
|
|
132
|
+
const m = t.match(/^entrada\s+id\s+"(.+?)"\s+dica\s+"(.+?)"/);
|
|
133
|
+
if (m) return `<input id="${m[1]}" placeholder="${m[2]}">`;
|
|
134
|
+
return `<input placeholder="${pegarTexto('entrada')}">`;
|
|
135
|
+
}
|
|
136
|
+
if (t.startsWith('caixa ')) return `<div class="${pegarTexto('caixa')}">`;
|
|
137
|
+
if (t === 'fim') return `</div>`;
|
|
138
|
+
|
|
139
|
+
return `<!-- linha ${idx + 1} não reconhecida: ${t} -->`;
|
|
140
|
+
}).join('\n');
|
|
54
141
|
}
|
|
55
142
|
|
|
56
143
|
function traduzirEstilo(conteudo) {
|
|
57
|
-
if(!conteudo) return "";
|
|
58
|
-
|
|
144
|
+
if (!conteudo) return "";
|
|
145
|
+
return conteudo
|
|
59
146
|
.replace(/fundo:/g, 'background:')
|
|
60
147
|
.replace(/cor-texto:/g, 'color:')
|
|
148
|
+
.replace(/tamanho-texto:/g, 'font-size:')
|
|
149
|
+
.replace(/margem:/g, 'margin:')
|
|
150
|
+
.replace(/borda:/g, 'border:')
|
|
151
|
+
.replace(/arredondado:/g, 'border-radius:')
|
|
61
152
|
.replace(/verde-neon/g, '#00ff88')
|
|
62
|
-
.replace(/amarelo-neon/g, '#ffff00')
|
|
153
|
+
.replace(/amarelo-neon/g, '#ffff00')
|
|
154
|
+
.replace(/azul-neon/g, '#00cfff')
|
|
155
|
+
.replace(/vermelho-neon/g, '#ff4444')
|
|
63
156
|
.replace(/ao-passar-mouse:/g, '&:hover')
|
|
64
|
-
.replace(/estilo
|
|
65
|
-
.replace(/
|
|
66
|
-
return css;
|
|
157
|
+
.replace(/estilo\s+/g, '.')
|
|
158
|
+
.replace(/\bfim\b/g, '}');
|
|
67
159
|
}
|
|
68
160
|
|
|
69
|
-
//
|
|
70
|
-
|
|
161
|
+
// ─────────────────────────────────────────
|
|
162
|
+
// TRADUTOR PRINCIPAL (RC → JS)
|
|
163
|
+
// ─────────────────────────────────────────
|
|
164
|
+
|
|
165
|
+
function traduzir(linha, numeroLinha, contexto) {
|
|
71
166
|
let t = linha.trim();
|
|
72
|
-
if (!t || t.startsWith("//")) return
|
|
73
|
-
|
|
74
|
-
//
|
|
167
|
+
if (!t || t.startsWith("//")) return linha; // preserva indentação
|
|
168
|
+
|
|
169
|
+
// Título da página
|
|
75
170
|
if (t.startsWith('pagina ')) {
|
|
76
|
-
ehSite = true;
|
|
77
|
-
|
|
171
|
+
contexto.ehSite = true;
|
|
172
|
+
const titulo = t.replace(/^pagina\s+/, '');
|
|
78
173
|
return `document.title = ${titulo};`;
|
|
79
174
|
}
|
|
80
175
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
176
|
+
// UI: mostrar elemento na tela pelo id
|
|
177
|
+
if (t.startsWith('mostrar_tela ')) {
|
|
178
|
+
const m = t.match(/^mostrar_tela\s+"(.+?)"\s+em\s+"(.+?)"/);
|
|
179
|
+
if (m) return `document.getElementById("${m[2]}").innerText = "${m[1]}";`;
|
|
180
|
+
}
|
|
85
181
|
|
|
86
|
-
//
|
|
87
|
-
if (t.startsWith('
|
|
182
|
+
// Ao clicar: evento de clique
|
|
183
|
+
if (t.startsWith('ao_clicar ')) {
|
|
184
|
+
const m = t.match(/^ao_clicar\s+"(.+?)"/);
|
|
185
|
+
if (m) return `document.getElementById("${m[1]}").addEventListener("click", function() {`;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// Comandos básicos
|
|
189
|
+
if (t.startsWith('alerta ')) return `alert(${t.replace(/^alerta\s+/, '')});`;
|
|
190
|
+
if (t.startsWith('mudar_fundo ')) return `document.body.style.background = ${t.replace(/^mudar_fundo\s+/, '')};`;
|
|
191
|
+
if (t.startsWith('mostrar ')) return `console.log(${t.replace(/^mostrar\s+/, '')});`;
|
|
192
|
+
|
|
193
|
+
// Variável com parsing correto de strings com espaços
|
|
88
194
|
if (t.startsWith('variavel ')) {
|
|
89
|
-
|
|
90
|
-
|
|
195
|
+
const m = t.match(/^variavel\s+(\w+)\s+(.*)/);
|
|
196
|
+
if (!m) erroDeCompilacao(`Sintaxe incorreta: "${t}" — Use: variavel nome "valor"`, numeroLinha);
|
|
197
|
+
return `let ${m[1]} = ${m[2]};`;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
if (t.startsWith('constante ')) {
|
|
201
|
+
const m = t.match(/^constante\s+(\w+)\s+(.*)/);
|
|
202
|
+
if (!m) erroDeCompilacao(`Sintaxe incorreta: "${t}" — Use: constante nome "valor"`, numeroLinha);
|
|
203
|
+
return `const ${m[1]} = ${m[2]};`;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
// Estruturas de controle
|
|
207
|
+
if (t.startsWith('se ')) return `if (${t.replace(/^se\s+/, '').replace(/\bend\b/, '')}) {`;
|
|
208
|
+
if (t === 'senao') return `} else {`;
|
|
209
|
+
if (t.startsWith('senaose ')) return `} else if (${t.replace(/^senaose\s+/, '')}) {`;
|
|
210
|
+
if (t === 'fim') return `}`;
|
|
211
|
+
|
|
212
|
+
// Loops
|
|
213
|
+
if (t.startsWith('repetir ')) {
|
|
214
|
+
const m = t.match(/^repetir\s+(\d+)\s+vezes/);
|
|
215
|
+
if (m) return `for (let _i = 0; _i < ${m[1]}; _i++) {`;
|
|
216
|
+
}
|
|
217
|
+
if (t.startsWith('enquanto ')) return `while (${t.replace(/^enquanto\s+/, '')}) {`;
|
|
218
|
+
|
|
219
|
+
// Funções
|
|
220
|
+
if (t.startsWith('funcao ')) {
|
|
221
|
+
const m = t.match(/^funcao\s+(\w+)\s*\((.*)\)/);
|
|
222
|
+
if (m) return `function ${m[1]}(${m[2]}) {`;
|
|
91
223
|
}
|
|
92
|
-
if (t.startsWith('
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
224
|
+
if (t.startsWith('retornar ')) return `return ${t.replace(/^retornar\s+/, '')};`;
|
|
225
|
+
|
|
226
|
+
return t; // passa JS puro direto
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// ─────────────────────────────────────────
|
|
230
|
+
// VALIDAÇÃO DE BLOCOS
|
|
231
|
+
// ─────────────────────────────────────────
|
|
232
|
+
function validarBlocos(linhas) {
|
|
233
|
+
let pilha = 0;
|
|
234
|
+
linhas.forEach((linha, idx) => {
|
|
235
|
+
const t = linha.trim();
|
|
236
|
+
if (t.startsWith('se ') || t.startsWith('enquanto ') || t.startsWith('funcao ') || t.startsWith('repetir ') || t.startsWith('ao_clicar ')) pilha++;
|
|
237
|
+
if (t === 'fim') pilha--;
|
|
238
|
+
if (pilha < 0) erroDeCompilacao(`"fim" sobrando sem um bloco aberto.`, idx + 1);
|
|
239
|
+
});
|
|
240
|
+
if (pilha > 0) erroDeCompilacao(`Faltam ${pilha} "fim" para fechar bloco(s) abertos.`, linhas.length);
|
|
96
241
|
}
|
|
97
242
|
|
|
98
|
-
//
|
|
243
|
+
// ─────────────────────────────────────────
|
|
244
|
+
// PONTO DE ENTRADA
|
|
245
|
+
// ─────────────────────────────────────────
|
|
99
246
|
if (!arquivoOuCmd) {
|
|
100
|
-
console.log("🌱 Raizcode
|
|
247
|
+
console.log("🌱 Raizcode v1.8 — A linguagem brasileira");
|
|
248
|
+
console.log(" Uso: raizcode <arquivo.rc>");
|
|
249
|
+
console.log(" Setup VSCode: raizcode --setup");
|
|
101
250
|
process.exit();
|
|
102
251
|
}
|
|
103
252
|
|
|
@@ -105,79 +254,140 @@ const caminho = path.resolve(arquivoOuCmd);
|
|
|
105
254
|
const nomeBase = caminho.substring(0, caminho.lastIndexOf('.'));
|
|
106
255
|
|
|
107
256
|
if (!fs.existsSync(caminho)) {
|
|
108
|
-
console.
|
|
257
|
+
console.error(`❌ Arquivo não encontrado: ${arquivoOuCmd}`);
|
|
109
258
|
process.exit(1);
|
|
110
259
|
}
|
|
111
260
|
|
|
112
261
|
try {
|
|
113
262
|
const arqRcx = nomeBase + '.rcx';
|
|
114
|
-
const arqRcc = nomeBase + '.rcc';
|
|
115
|
-
|
|
263
|
+
const arqRcc = nomeBase + '.rcc';
|
|
264
|
+
|
|
116
265
|
let htmlExtra = "";
|
|
117
266
|
let cssExtra = "";
|
|
267
|
+
const contexto = { ehSite: false };
|
|
118
268
|
|
|
119
269
|
if (fs.existsSync(arqRcx)) {
|
|
120
270
|
htmlExtra = traduzirEstrutura(fs.readFileSync(arqRcx, 'utf-8'));
|
|
121
|
-
ehSite = true;
|
|
271
|
+
contexto.ehSite = true;
|
|
122
272
|
}
|
|
123
|
-
if (fs.existsSync(arqRcc)) {
|
|
273
|
+
if (fs.existsSync(arqRcc)) {
|
|
124
274
|
cssExtra = traduzirEstilo(fs.readFileSync(arqRcc, 'utf-8'));
|
|
125
|
-
ehSite = true;
|
|
275
|
+
contexto.ehSite = true;
|
|
126
276
|
}
|
|
127
277
|
|
|
128
278
|
const codigo = fs.readFileSync(caminho, 'utf-8');
|
|
129
|
-
const
|
|
130
|
-
|
|
131
|
-
|
|
279
|
+
const linhas = codigo.split('\n');
|
|
280
|
+
|
|
281
|
+
// Valida antes de compilar
|
|
282
|
+
validarBlocos(linhas);
|
|
283
|
+
|
|
284
|
+
const js = linhas.map((linha, idx) => traduzir(linha, idx + 1, contexto)).join('\n');
|
|
285
|
+
|
|
286
|
+
const saidaJS = nomeBase + '.js';
|
|
132
287
|
const saidaHTML = nomeBase + '.html';
|
|
133
288
|
|
|
134
|
-
if (ehSite) {
|
|
135
|
-
const
|
|
136
|
-
|
|
289
|
+
if (contexto.ehSite) {
|
|
290
|
+
const porta = args[1] ? parseInt(args[1]) : 3000;
|
|
291
|
+
const estruturaHTML = `<!DOCTYPE html>
|
|
137
292
|
<html lang="pt-br">
|
|
138
293
|
<head>
|
|
139
294
|
<meta charset="UTF-8">
|
|
140
295
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
296
|
+
<title>Raizcode</title>
|
|
141
297
|
<style>
|
|
142
|
-
|
|
143
|
-
|
|
298
|
+
* { box-sizing: border-box; }
|
|
299
|
+
body {
|
|
300
|
+
background: #0d0d0d;
|
|
301
|
+
color: #f0f0f0;
|
|
302
|
+
font-family: sans-serif;
|
|
303
|
+
display: flex;
|
|
304
|
+
justify-content: center;
|
|
305
|
+
align-items: center;
|
|
306
|
+
min-height: 100vh;
|
|
307
|
+
margin: 0;
|
|
308
|
+
padding: 20px;
|
|
309
|
+
}
|
|
310
|
+
#raiz-app {
|
|
311
|
+
text-align: center;
|
|
312
|
+
border: 1px solid #00ff88;
|
|
313
|
+
padding: 40px;
|
|
314
|
+
border-radius: 20px;
|
|
315
|
+
background: #1a1a1a;
|
|
316
|
+
box-shadow: 0 0 30px rgba(0,255,136,0.2);
|
|
317
|
+
max-width: 800px;
|
|
318
|
+
width: 100%;
|
|
319
|
+
}
|
|
144
320
|
h1 { color: #00ff88; text-shadow: 0 0 10px #00ff88; }
|
|
145
|
-
|
|
321
|
+
h2 { color: #00cfff; }
|
|
322
|
+
a { color: #00ff88; }
|
|
323
|
+
button {
|
|
324
|
+
background: #00ff88;
|
|
325
|
+
color: #000;
|
|
326
|
+
border: none;
|
|
327
|
+
padding: 12px 28px;
|
|
328
|
+
border-radius: 10px;
|
|
329
|
+
font-weight: bold;
|
|
330
|
+
cursor: pointer;
|
|
331
|
+
margin: 8px;
|
|
332
|
+
font-size: 1rem;
|
|
333
|
+
transition: opacity 0.2s;
|
|
334
|
+
}
|
|
335
|
+
button:hover { opacity: 0.8; }
|
|
336
|
+
input {
|
|
337
|
+
background: #111;
|
|
338
|
+
border: 1px solid #00ff88;
|
|
339
|
+
color: #fff;
|
|
340
|
+
padding: 10px 16px;
|
|
341
|
+
border-radius: 8px;
|
|
342
|
+
margin: 8px;
|
|
343
|
+
font-size: 1rem;
|
|
344
|
+
}
|
|
146
345
|
${cssExtra}
|
|
147
346
|
</style>
|
|
148
347
|
</head>
|
|
149
348
|
<body>
|
|
150
349
|
<div id="raiz-app">${htmlExtra}</div>
|
|
151
|
-
<script
|
|
350
|
+
<script>
|
|
351
|
+
${js}
|
|
352
|
+
</script>
|
|
152
353
|
</body>
|
|
153
354
|
</html>`;
|
|
154
|
-
|
|
155
|
-
//
|
|
355
|
+
|
|
356
|
+
// Salva HTML para inspeção (opcional)
|
|
357
|
+
fs.writeFileSync(saidaHTML, estruturaHTML);
|
|
358
|
+
|
|
156
359
|
const server = http.createServer((req, res) => {
|
|
157
|
-
res.writeHead(200, { 'Content-Type': 'text/html' });
|
|
360
|
+
res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
|
|
158
361
|
res.end(estruturaHTML);
|
|
159
362
|
});
|
|
160
363
|
|
|
161
|
-
server.listen(
|
|
162
|
-
console.log(
|
|
163
|
-
|
|
364
|
+
server.listen(porta, () => {
|
|
365
|
+
console.log(`\n🌱 Raizcode — Servidor ativo!`);
|
|
366
|
+
console.log(`🌐 Acesse: http://localhost:${porta}`);
|
|
367
|
+
console.log(`⏹ Pressione Ctrl+C para encerrar.\n`);
|
|
368
|
+
abrirNavegador(`http://localhost:${porta}`);
|
|
164
369
|
});
|
|
165
370
|
|
|
166
|
-
//
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
// LIMPEZA que você pediu: Apaga depois de um tempo para não poluir
|
|
170
|
-
setTimeout(() => {
|
|
371
|
+
// Mantém servidor vivo até Ctrl+C
|
|
372
|
+
process.on('SIGINT', () => {
|
|
373
|
+
console.log('\n👋 Servidor encerrado.');
|
|
171
374
|
if (fs.existsSync(saidaHTML)) fs.unlinkSync(saidaHTML);
|
|
172
|
-
if (fs.existsSync(saidaJS)) fs.unlinkSync(saidaJS);
|
|
173
375
|
process.exit();
|
|
174
|
-
}
|
|
376
|
+
});
|
|
175
377
|
|
|
176
378
|
} else {
|
|
379
|
+
// Modo script: executa e apaga
|
|
177
380
|
fs.writeFileSync(saidaJS, js);
|
|
178
|
-
|
|
179
|
-
|
|
381
|
+
try {
|
|
382
|
+
execSync(`node "${saidaJS}"`, { stdio: 'inherit' });
|
|
383
|
+
} finally {
|
|
384
|
+
if (fs.existsSync(saidaJS)) fs.unlinkSync(saidaJS);
|
|
385
|
+
}
|
|
180
386
|
}
|
|
387
|
+
|
|
181
388
|
} catch (err) {
|
|
182
|
-
|
|
389
|
+
if (!err.already_reported) {
|
|
390
|
+
console.error(`\n❌ Erro inesperado: ${err.message}\n`);
|
|
391
|
+
}
|
|
392
|
+
process.exit(1);
|
|
183
393
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "raizcode-ofc",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "Linguagem de programação
|
|
3
|
+
"version": "1.9.0",
|
|
4
|
+
"description": "Linguagem de programação brasileira — escreva código em português.",
|
|
5
5
|
"main": "compilador.js",
|
|
6
6
|
"bin": {
|
|
7
7
|
"raizcode": "./compilador.js"
|
|
@@ -15,10 +15,13 @@
|
|
|
15
15
|
"raizcode",
|
|
16
16
|
"linguagem",
|
|
17
17
|
"portugues",
|
|
18
|
+
"pt-br",
|
|
18
19
|
"compilador",
|
|
19
20
|
"javascript",
|
|
20
21
|
"web",
|
|
21
|
-
"desenvolvimento"
|
|
22
|
+
"desenvolvimento",
|
|
23
|
+
"iniciantes",
|
|
24
|
+
"educacao"
|
|
22
25
|
],
|
|
23
26
|
"author": "Riquefla",
|
|
24
27
|
"license": "MIT",
|
|
@@ -26,40 +29,11 @@
|
|
|
26
29
|
"node": ">=14.0.0"
|
|
27
30
|
},
|
|
28
31
|
"files": [
|
|
32
|
+
"compilador.js",
|
|
29
33
|
"icons/",
|
|
30
34
|
"syntaxes/",
|
|
31
|
-
"
|
|
32
|
-
"
|
|
33
|
-
"
|
|
34
|
-
]
|
|
35
|
-
"contributes": {
|
|
36
|
-
"languages": [
|
|
37
|
-
{
|
|
38
|
-
"id": "raizcode",
|
|
39
|
-
"aliases": ["Raizcode", "rc"],
|
|
40
|
-
"extensions": [".rc"],
|
|
41
|
-
"configuration": "./language-configuration.json",
|
|
42
|
-
"icon": { "dark": "./icons/rc.png", "light": "./icons/rc.png" }
|
|
43
|
-
},
|
|
44
|
-
{
|
|
45
|
-
"id": "raizcode-estrutura",
|
|
46
|
-
"aliases": ["Raizcode Estrutura", "rcx"],
|
|
47
|
-
"extensions": [".rcx"],
|
|
48
|
-
"icon": { "dark": "./icons/rcx.png", "light": "./icons/rcx.png" }
|
|
49
|
-
},
|
|
50
|
-
{
|
|
51
|
-
"id": "raizcode-estilo",
|
|
52
|
-
"aliases": ["Raizcode Estilo", "rcc"],
|
|
53
|
-
"extensions": [".rcc"],
|
|
54
|
-
"icon": { "dark": "./icons/rcc.png", "light": "./icons/rcc.png" }
|
|
55
|
-
}
|
|
56
|
-
],
|
|
57
|
-
"grammars": [
|
|
58
|
-
{
|
|
59
|
-
"language": "raizcode",
|
|
60
|
-
"scopeName": "source.rc",
|
|
61
|
-
"path": "./syntaxes/raizcode.tmLanguage.json"
|
|
62
|
-
}
|
|
63
|
-
]
|
|
64
|
-
}
|
|
35
|
+
"exemplos/",
|
|
36
|
+
"README.md",
|
|
37
|
+
"package.json"
|
|
38
|
+
]
|
|
65
39
|
}
|