delegua-arm 0.0.1
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/README.md +147 -0
- package/dist/compilador-arm.d.ts +5 -0
- package/dist/compilador-arm.d.ts.map +1 -0
- package/dist/compilador-arm.js +120 -0
- package/dist/compilador-arm.js.map +1 -0
- package/dist/ilc.d.ts +3 -0
- package/dist/ilc.d.ts.map +1 -0
- package/dist/ilc.js +184 -0
- package/dist/ilc.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -0
- package/dist/interfaces/index.d.ts +3 -0
- package/dist/interfaces/index.d.ts.map +1 -0
- package/dist/interfaces/index.js +19 -0
- package/dist/interfaces/index.js.map +1 -0
- package/dist/interfaces/opcoes-compilacao-interface.d.ts +11 -0
- package/dist/interfaces/opcoes-compilacao-interface.d.ts.map +1 -0
- package/dist/interfaces/opcoes-compilacao-interface.js +3 -0
- package/dist/interfaces/opcoes-compilacao-interface.js.map +1 -0
- package/dist/interfaces/resultado-compilacao-interface.d.ts +6 -0
- package/dist/interfaces/resultado-compilacao-interface.d.ts.map +1 -0
- package/dist/interfaces/resultado-compilacao-interface.js +3 -0
- package/dist/interfaces/resultado-compilacao-interface.js.map +1 -0
- package/dist/verificador-toolchain.d.ts +15 -0
- package/dist/verificador-toolchain.d.ts.map +1 -0
- package/dist/verificador-toolchain.js +74 -0
- package/dist/verificador-toolchain.js.map +1 -0
- package/fontes/compilador-arm.ts +100 -0
- package/fontes/ilc.ts +173 -0
- package/fontes/index.ts +2 -0
- package/fontes/interfaces/index.ts +2 -0
- package/fontes/interfaces/opcoes-compilacao-interface.ts +10 -0
- package/fontes/interfaces/resultado-compilacao-interface.ts +5 -0
- package/fontes/verificador-toolchain.ts +92 -0
- package/package.json +35 -0
- package/tsconfig.json +14 -0
package/README.md
ADDED
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
# delegua-arm
|
|
2
|
+
|
|
3
|
+
Compilador Delégua para binários ARM nativos, sem LLVM. Utiliza o tradutor de assembly ARM da biblioteca `@designliquido/delegua` e o toolchain GNU para montagem e linkagem.
|
|
4
|
+
|
|
5
|
+
## Pipeline de compilação
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
arquivo.delegua → Lexador → AvaliadorSintatico → TradutorAssemblyARM → arquivo.s → GNU as → arquivo.o → GNU ld → binário
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Plataformas alvo
|
|
12
|
+
|
|
13
|
+
| Alvo | Descrição |
|
|
14
|
+
|-------------|----------------------------------------|
|
|
15
|
+
| `linux-arm` | Linux em arquitetura ARM (padrão) |
|
|
16
|
+
| `android` | Android via Android NDK |
|
|
17
|
+
|
|
18
|
+
## Pré-requisitos
|
|
19
|
+
|
|
20
|
+
### Linux ARM (`linux-arm`)
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
apt install gcc-arm-linux-gnueabihf binutils-arm-linux-gnueabihf
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Ferramentas necessárias no `PATH`:
|
|
27
|
+
|
|
28
|
+
| Ferramenta | Função |
|
|
29
|
+
|-----------------------------|---------------------------------|
|
|
30
|
+
| `arm-linux-gnueabihf-as` | Montador GNU para ARM |
|
|
31
|
+
| `arm-linux-gnueabihf-ld` | Linker GNU para ARM |
|
|
32
|
+
|
|
33
|
+
### Android (`android`)
|
|
34
|
+
|
|
35
|
+
Instale o [Android NDK](https://developer.android.com/ndk) e adicione o diretório `toolchains/arm-linux-androideabi-*/prebuilt/*/bin` ao `PATH`.
|
|
36
|
+
|
|
37
|
+
Ferramentas necessárias no `PATH`:
|
|
38
|
+
|
|
39
|
+
| Ferramenta | Função |
|
|
40
|
+
|---------------------------------|---------------------------------|
|
|
41
|
+
| `arm-linux-androideabi-as` | Montador NDK para ARM |
|
|
42
|
+
| `arm-linux-androideabi-ld` | Linker NDK para ARM |
|
|
43
|
+
|
|
44
|
+
## Instalação
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
npm install -g delegua-arm
|
|
48
|
+
# ou
|
|
49
|
+
yarn global add delegua-arm
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Uso (CLI)
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
npx delegua-arm <arquivo.delegua> [opções]
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Opções
|
|
59
|
+
|
|
60
|
+
| Opção | Descrição |
|
|
61
|
+
|-----------------------------|---------------------------------------------------------------|
|
|
62
|
+
| `-o <nome>` | Nome do binário de saída (sem extensão). Padrão: nome do arquivo de entrada. |
|
|
63
|
+
| `--alvo <linux-arm\|android>` | Plataforma alvo. Padrão: `linux-arm`. |
|
|
64
|
+
| `--manter-temporarios` | Mantém os arquivos intermediários (`.s`, `.o`) após compilar. |
|
|
65
|
+
|
|
66
|
+
### Exemplos
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
# Compilar para Linux ARM (padrão)
|
|
70
|
+
npx delegua-arm programa.delegua
|
|
71
|
+
|
|
72
|
+
# Compilar com nome de saída personalizado
|
|
73
|
+
npx delegua-arm programa.delegua -o meu-programa
|
|
74
|
+
|
|
75
|
+
# Compilar para Android
|
|
76
|
+
npx delegua-arm programa.delegua --alvo android
|
|
77
|
+
|
|
78
|
+
# Inspecionar o assembly gerado sem remover os temporários
|
|
79
|
+
npx delegua-arm programa.delegua --manter-temporarios
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Uso (API)
|
|
83
|
+
|
|
84
|
+
```typescript
|
|
85
|
+
import { CompiladorARM } from 'delegua-arm';
|
|
86
|
+
|
|
87
|
+
const compilador = new CompiladorARM();
|
|
88
|
+
const resultado = await compilador.compilar({
|
|
89
|
+
arquivoEntrada: 'programa.delegua',
|
|
90
|
+
nomeSaida: 'programa', // opcional
|
|
91
|
+
alvo: 'linux-arm', // opcional, padrão: 'linux-arm'
|
|
92
|
+
manterTemporarios: false, // opcional
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
if (resultado.sucesso) {
|
|
96
|
+
console.log('Binário gerado em:', resultado.caminhoBinario);
|
|
97
|
+
} else {
|
|
98
|
+
console.error('Erro:', resultado.erro);
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### `OpcaoesCompilacao`
|
|
103
|
+
|
|
104
|
+
| Campo | Tipo | Obrigatório | Descrição |
|
|
105
|
+
|----------------------|-----------------------------|-------------|----------------------------------------------------|
|
|
106
|
+
| `arquivoEntrada` | `string` | Sim | Caminho para o arquivo `.delegua`. |
|
|
107
|
+
| `nomeSaida` | `string` | Não | Nome do binário de saída (sem extensão). |
|
|
108
|
+
| `alvo` | `'linux-arm' \| 'android'` | Não | Plataforma alvo. Padrão: `'linux-arm'`. |
|
|
109
|
+
| `manterTemporarios` | `boolean` | Não | Preserva `.s` e `.o` após compilar. |
|
|
110
|
+
|
|
111
|
+
### `ResultadoCompilacao`
|
|
112
|
+
|
|
113
|
+
| Campo | Tipo | Descrição |
|
|
114
|
+
|------------------|-----------|-------------------------------------------------|
|
|
115
|
+
| `sucesso` | `boolean` | `true` se a compilação foi bem-sucedida. |
|
|
116
|
+
| `caminhoBinario` | `string` | Caminho para o binário gerado (se bem-sucedido).|
|
|
117
|
+
| `erro` | `string` | Mensagem de erro (se mal-sucedido). |
|
|
118
|
+
|
|
119
|
+
## Desenvolvimento
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
# Instalar dependências
|
|
123
|
+
yarn install
|
|
124
|
+
|
|
125
|
+
# Compilar o pacote
|
|
126
|
+
yarn empacotar
|
|
127
|
+
|
|
128
|
+
# Executar testes
|
|
129
|
+
yarn testes-unitarios
|
|
130
|
+
|
|
131
|
+
# Executar direto via ts-node
|
|
132
|
+
yarn executar programa.delegua
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
## Comparação com `delegua-x64`
|
|
136
|
+
|
|
137
|
+
| Aspecto | `delegua-x64` | `delegua-arm` |
|
|
138
|
+
|-----------------------|----------------------------------|--------------------------------------------|
|
|
139
|
+
| Tradutor | `TradutorAssemblyX64` | `TradutorAssemblyARM` |
|
|
140
|
+
| Alvos | `linux`, `windows` | `linux-arm`, `android` |
|
|
141
|
+
| Montador | `nasm -f elf64/win64` | `arm-linux-gnueabihf-as` / `arm-linux-androideabi-as` |
|
|
142
|
+
| Linker | `ld` / `gcc` | `arm-linux-gnueabihf-ld` / `arm-linux-androideabi-ld` |
|
|
143
|
+
| Arquivo intermediário | `.asm` | `.s` |
|
|
144
|
+
|
|
145
|
+
## Licença
|
|
146
|
+
|
|
147
|
+
MIT
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compilador-arm.d.ts","sourceRoot":"","sources":["../fontes/compilador-arm.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAEtE,qBAAa,aAAa;IAChB,QAAQ,CAAC,MAAM,EAAE,iBAAiB,GAAG,OAAO,CAAC,mBAAmB,CAAC;CA0F1E"}
|
|
@@ -0,0 +1,120 @@
|
|
|
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.CompiladorARM = void 0;
|
|
37
|
+
const fs = __importStar(require("fs"));
|
|
38
|
+
const path = __importStar(require("path"));
|
|
39
|
+
const child_process_1 = require("child_process");
|
|
40
|
+
const delegua_1 = require("@designliquido/delegua");
|
|
41
|
+
const verificador_toolchain_1 = require("./verificador-toolchain");
|
|
42
|
+
class CompiladorARM {
|
|
43
|
+
async compilar(opcoes) {
|
|
44
|
+
var _a, _b, _c;
|
|
45
|
+
const alvo = (_a = opcoes.alvo) !== null && _a !== void 0 ? _a : 'linux-arm';
|
|
46
|
+
const resultado = (0, verificador_toolchain_1.verificarToolchain)(alvo);
|
|
47
|
+
if (!resultado.sucesso) {
|
|
48
|
+
const nomes = resultado.ferramentasFaltando
|
|
49
|
+
.map((f) => ` • ${f.nome}: ${f.mensagemAjuda}`)
|
|
50
|
+
.join('\n');
|
|
51
|
+
return {
|
|
52
|
+
sucesso: false,
|
|
53
|
+
erro: `Ferramentas obrigatórias não encontradas no PATH:\n${nomes}`,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
const { arquivoEntrada, nomeSaida, manterTemporarios } = opcoes;
|
|
57
|
+
const nomeBase = path.basename(arquivoEntrada, path.extname(arquivoEntrada));
|
|
58
|
+
const nomeBinario = nomeSaida || nomeBase;
|
|
59
|
+
const diretorioSaida = path.dirname(arquivoEntrada);
|
|
60
|
+
const caminhoBinario = path.join(diretorioSaida, nomeBinario);
|
|
61
|
+
const arquivosTemporarios = [];
|
|
62
|
+
const prefixoToolchain = alvo === 'android' ? 'arm-linux-androideabi' : 'arm-linux-gnueabihf';
|
|
63
|
+
try {
|
|
64
|
+
// 1. Ler e lexar o fonte
|
|
65
|
+
const conteudo = fs.readFileSync(arquivoEntrada, 'utf-8');
|
|
66
|
+
const linhas = conteudo.split('\n');
|
|
67
|
+
const lexador = new delegua_1.Lexador();
|
|
68
|
+
const resultadoLex = lexador.mapear(linhas, -1);
|
|
69
|
+
if (resultadoLex.erros && resultadoLex.erros.length > 0) {
|
|
70
|
+
const msgs = resultadoLex.erros.map((e) => String(e)).join('\n');
|
|
71
|
+
return { sucesso: false, erro: `Erros léxicos:\n${msgs}` };
|
|
72
|
+
}
|
|
73
|
+
// 2. Analisar sintaticamente
|
|
74
|
+
const avaliador = new delegua_1.AvaliadorSintatico();
|
|
75
|
+
const resultadoParse = await avaliador.analisar(resultadoLex, -1);
|
|
76
|
+
if (resultadoParse.erros && resultadoParse.erros.length > 0) {
|
|
77
|
+
const msgs = resultadoParse.erros.map((e) => String(e)).join('\n');
|
|
78
|
+
return { sucesso: false, erro: `Erros sintáticos:\n${msgs}` };
|
|
79
|
+
}
|
|
80
|
+
// 3. Traduzir para assembly ARM (GAS)
|
|
81
|
+
const tradutor = new delegua_1.TradutorAssemblyARM(alvo);
|
|
82
|
+
const assembly = tradutor.traduzir(resultadoParse.declaracoes);
|
|
83
|
+
// 4. Gravar arquivo .s
|
|
84
|
+
const caminhoAsm = path.join(diretorioSaida, `${nomeBase}.s`);
|
|
85
|
+
fs.writeFileSync(caminhoAsm, assembly, 'utf-8');
|
|
86
|
+
arquivosTemporarios.push(caminhoAsm);
|
|
87
|
+
// 5. Montar com GNU Assembler (cross-assembler para ARM)
|
|
88
|
+
const caminhoObj = path.join(diretorioSaida, `${nomeBase}.o`);
|
|
89
|
+
(0, child_process_1.execSync)(`${prefixoToolchain}-as "${caminhoAsm}" -o "${caminhoObj}"`, { stdio: 'pipe' });
|
|
90
|
+
arquivosTemporarios.push(caminhoObj);
|
|
91
|
+
// 6. Linkar
|
|
92
|
+
(0, child_process_1.execSync)(`${prefixoToolchain}-ld "${caminhoObj}" -o "${caminhoBinario}"`, { stdio: 'pipe' });
|
|
93
|
+
// 7. Limpar temporários
|
|
94
|
+
if (!manterTemporarios) {
|
|
95
|
+
for (const arquivo of arquivosTemporarios) {
|
|
96
|
+
if (fs.existsSync(arquivo)) {
|
|
97
|
+
fs.unlinkSync(arquivo);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return { sucesso: true, caminhoBinario };
|
|
102
|
+
}
|
|
103
|
+
catch (erro) {
|
|
104
|
+
if (!manterTemporarios) {
|
|
105
|
+
for (const arquivo of arquivosTemporarios) {
|
|
106
|
+
if (fs.existsSync(arquivo)) {
|
|
107
|
+
fs.unlinkSync(arquivo);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
const mensagem = ((_b = erro.stderr) === null || _b === void 0 ? void 0 : _b.toString().trim()) ||
|
|
112
|
+
((_c = erro.stdout) === null || _c === void 0 ? void 0 : _c.toString().trim()) ||
|
|
113
|
+
erro.message ||
|
|
114
|
+
String(erro);
|
|
115
|
+
return { sucesso: false, erro: mensagem };
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
exports.CompiladorARM = CompiladorARM;
|
|
120
|
+
//# sourceMappingURL=compilador-arm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compilador-arm.js","sourceRoot":"","sources":["../fontes/compilador-arm.ts"],"names":[],"mappings":"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"}
|
package/dist/ilc.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ilc.d.ts","sourceRoot":"","sources":["../fontes/ilc.ts"],"names":[],"mappings":""}
|
package/dist/ilc.js
ADDED
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
4
|
+
if (k2 === undefined) k2 = k;
|
|
5
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
6
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
7
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
8
|
+
}
|
|
9
|
+
Object.defineProperty(o, k2, desc);
|
|
10
|
+
}) : (function(o, m, k, k2) {
|
|
11
|
+
if (k2 === undefined) k2 = k;
|
|
12
|
+
o[k2] = m[k];
|
|
13
|
+
}));
|
|
14
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
15
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
16
|
+
}) : function(o, v) {
|
|
17
|
+
o["default"] = v;
|
|
18
|
+
});
|
|
19
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
20
|
+
var ownKeys = function(o) {
|
|
21
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
22
|
+
var ar = [];
|
|
23
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
24
|
+
return ar;
|
|
25
|
+
};
|
|
26
|
+
return ownKeys(o);
|
|
27
|
+
};
|
|
28
|
+
return function (mod) {
|
|
29
|
+
if (mod && mod.__esModule) return mod;
|
|
30
|
+
var result = {};
|
|
31
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
32
|
+
__setModuleDefault(result, mod);
|
|
33
|
+
return result;
|
|
34
|
+
};
|
|
35
|
+
})();
|
|
36
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
37
|
+
const path = __importStar(require("path"));
|
|
38
|
+
const fs = __importStar(require("fs"));
|
|
39
|
+
const compilador_arm_1 = require("./compilador-arm");
|
|
40
|
+
const verificador_toolchain_1 = require("./verificador-toolchain");
|
|
41
|
+
const CORES = {
|
|
42
|
+
reset: '\x1b[0m',
|
|
43
|
+
verde: '\x1b[32m',
|
|
44
|
+
amarelo: '\x1b[33m',
|
|
45
|
+
azul: '\x1b[34m',
|
|
46
|
+
magenta: '\x1b[35m',
|
|
47
|
+
ciano: '\x1b[36m',
|
|
48
|
+
vermelho: '\x1b[31m',
|
|
49
|
+
negrito: '\x1b[1m',
|
|
50
|
+
};
|
|
51
|
+
const LOGO = `
|
|
52
|
+
╔══════════════════════════════════════════════════════════════════╗
|
|
53
|
+
║ ║
|
|
54
|
+
║ ██████╗ ███████╗██╗ ███████╗ ██████╗ ██╗ ██╗ █████╗ ║
|
|
55
|
+
║ ██╔══██╗██╔════╝██║ ██╔════╝██╔════╝ ██║ ██║██╔══██╗ ║
|
|
56
|
+
║ ██║ ██║█████╗ ██║ █████╗ ██║ ███╗██║ ██║███████║ ║
|
|
57
|
+
║ ██║ ██║██╔══╝ ██║ ██╔══╝ ██║ ██║██║ ██║██╔══██║ ║
|
|
58
|
+
║ ██████╔╝███████╗███████╗███████╗╚██████╔╝╚██████╔╝██║ ██║ ║
|
|
59
|
+
║ ╚═════╝ ╚══════╝╚══════╝╚══════╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝ ║
|
|
60
|
+
║ ║
|
|
61
|
+
║ █████╗ ██████╗ ███╗ ███╗ ║
|
|
62
|
+
║ ██╔══██╗██╔══██╗████╗ ████║ ║
|
|
63
|
+
║ ███████║██████╔╝██╔████╔██║ ║
|
|
64
|
+
║ ██╔══██║██╔══██╗██║╚██╔╝██║ ║
|
|
65
|
+
║ ██║ ██║██║ ██║██║ ╚═╝ ██║ ║
|
|
66
|
+
║ ╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═╝ ║
|
|
67
|
+
║ ║
|
|
68
|
+
║ Compilador Delégua → GAS → Nativo ARM ║
|
|
69
|
+
╚══════════════════════════════════════════════════════════════════╝
|
|
70
|
+
`;
|
|
71
|
+
function logEtapa(etapa) {
|
|
72
|
+
console.log(`\n${CORES.ciano}${CORES.negrito}▶ ${etapa}${CORES.reset}`);
|
|
73
|
+
}
|
|
74
|
+
function logSucesso(mensagem) {
|
|
75
|
+
console.log(`${CORES.verde} ✓ ${mensagem}${CORES.reset}`);
|
|
76
|
+
}
|
|
77
|
+
function logInfo(mensagem) {
|
|
78
|
+
console.log(`${CORES.azul} ℹ ${mensagem}${CORES.reset}`);
|
|
79
|
+
}
|
|
80
|
+
function logAviso(mensagem) {
|
|
81
|
+
console.log(`${CORES.amarelo} ⚠ ${mensagem}${CORES.reset}`);
|
|
82
|
+
}
|
|
83
|
+
function logErro(mensagem) {
|
|
84
|
+
console.log(`${CORES.vermelho} ✗ ${mensagem}${CORES.reset}`);
|
|
85
|
+
}
|
|
86
|
+
function exibirAjuda() {
|
|
87
|
+
console.log(`${CORES.amarelo}Uso:${CORES.reset}`);
|
|
88
|
+
console.log(` npx delegua-arm <arquivo.delegua>`);
|
|
89
|
+
console.log('');
|
|
90
|
+
console.log(`${CORES.amarelo}Opções:${CORES.reset}`);
|
|
91
|
+
console.log(` -o <nome> Nome do binário de saída`);
|
|
92
|
+
console.log(` --alvo <linux-arm|android> Plataforma alvo (padrão: linux-arm)`);
|
|
93
|
+
console.log(` --manter-temporarios Não remove arquivos .s e .o após compilar`);
|
|
94
|
+
console.log('');
|
|
95
|
+
}
|
|
96
|
+
function verificarEReportarToolchain(alvo) {
|
|
97
|
+
logEtapa('Verificando ferramentas do toolchain');
|
|
98
|
+
const resultado = (0, verificador_toolchain_1.verificarToolchain)(alvo);
|
|
99
|
+
for (const ferramenta of resultado.ferramentasDisponiveis) {
|
|
100
|
+
logSucesso(`${ferramenta.nome} encontrado`);
|
|
101
|
+
}
|
|
102
|
+
for (const ferramenta of resultado.avisos) {
|
|
103
|
+
logAviso(`${ferramenta.nome} não encontrado (opcional)`);
|
|
104
|
+
logAviso(` ${ferramenta.mensagemAjuda}`);
|
|
105
|
+
}
|
|
106
|
+
for (const ferramenta of resultado.ferramentasFaltando) {
|
|
107
|
+
logErro(`${ferramenta.nome} não encontrado`);
|
|
108
|
+
logErro(` ${ferramenta.mensagemAjuda}`);
|
|
109
|
+
}
|
|
110
|
+
if (!resultado.sucesso) {
|
|
111
|
+
console.log('');
|
|
112
|
+
logErro('Compilação cancelada. Instale as ferramentas acima e tente novamente.');
|
|
113
|
+
}
|
|
114
|
+
return resultado.sucesso;
|
|
115
|
+
}
|
|
116
|
+
async function principal() {
|
|
117
|
+
console.log(CORES.magenta + LOGO + CORES.reset);
|
|
118
|
+
const args = process.argv.slice(2);
|
|
119
|
+
if (args.length === 0) {
|
|
120
|
+
exibirAjuda();
|
|
121
|
+
process.exit(1);
|
|
122
|
+
}
|
|
123
|
+
let arquivoEntrada = '';
|
|
124
|
+
let nomeSaida = '';
|
|
125
|
+
let alvo;
|
|
126
|
+
let manterTemporarios = false;
|
|
127
|
+
for (let i = 0; i < args.length; i++) {
|
|
128
|
+
if (args[i] === '-o' && args[i + 1]) {
|
|
129
|
+
nomeSaida = args[++i];
|
|
130
|
+
}
|
|
131
|
+
else if (args[i] === '--alvo' && args[i + 1]) {
|
|
132
|
+
const valor = args[++i];
|
|
133
|
+
if (valor !== 'linux-arm' && valor !== 'android') {
|
|
134
|
+
logErro(`Alvo inválido: "${valor}". Use linux-arm ou android.`);
|
|
135
|
+
process.exit(1);
|
|
136
|
+
}
|
|
137
|
+
alvo = valor;
|
|
138
|
+
}
|
|
139
|
+
else if (args[i] === '--manter-temporarios') {
|
|
140
|
+
manterTemporarios = true;
|
|
141
|
+
}
|
|
142
|
+
else if (!arquivoEntrada) {
|
|
143
|
+
arquivoEntrada = args[i];
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
if (!arquivoEntrada) {
|
|
147
|
+
logErro('Arquivo de entrada não especificado.');
|
|
148
|
+
exibirAjuda();
|
|
149
|
+
process.exit(1);
|
|
150
|
+
}
|
|
151
|
+
if (!fs.existsSync(arquivoEntrada)) {
|
|
152
|
+
logErro(`Arquivo não encontrado: ${arquivoEntrada}`);
|
|
153
|
+
process.exit(1);
|
|
154
|
+
}
|
|
155
|
+
if (!verificarEReportarToolchain(alvo)) {
|
|
156
|
+
process.exit(1);
|
|
157
|
+
}
|
|
158
|
+
logEtapa('Iniciando compilação');
|
|
159
|
+
logInfo(`Arquivo: ${arquivoEntrada}`);
|
|
160
|
+
if (alvo)
|
|
161
|
+
logInfo(`Alvo: ${alvo}`);
|
|
162
|
+
const compilador = new compilador_arm_1.CompiladorARM();
|
|
163
|
+
const resultado = await compilador.compilar({
|
|
164
|
+
arquivoEntrada,
|
|
165
|
+
nomeSaida,
|
|
166
|
+
alvo,
|
|
167
|
+
manterTemporarios,
|
|
168
|
+
});
|
|
169
|
+
if (!resultado.sucesso) {
|
|
170
|
+
logErro('Erro durante a compilação:');
|
|
171
|
+
console.error(resultado.erro);
|
|
172
|
+
process.exit(1);
|
|
173
|
+
}
|
|
174
|
+
console.log('');
|
|
175
|
+
console.log(`${CORES.verde}${CORES.negrito}════════════════════════════════════════════════════════════════${CORES.reset}`);
|
|
176
|
+
console.log(`${CORES.verde}${CORES.negrito} ✓ Compilação concluída com sucesso!${CORES.reset}`);
|
|
177
|
+
console.log(`${CORES.verde}${CORES.negrito}════════════════════════════════════════════════════════════════${CORES.reset}`);
|
|
178
|
+
console.log('');
|
|
179
|
+
logInfo(`Binário: ${CORES.negrito}${resultado.caminhoBinario}${CORES.reset}`);
|
|
180
|
+
logInfo(`Para executar: ${CORES.negrito}./${path.relative('.', resultado.caminhoBinario)}${CORES.reset}`);
|
|
181
|
+
console.log('');
|
|
182
|
+
}
|
|
183
|
+
principal();
|
|
184
|
+
//# sourceMappingURL=ilc.js.map
|
package/dist/ilc.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ilc.js","sourceRoot":"","sources":["../fontes/ilc.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../fontes/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC;AACjC,cAAc,yBAAyB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
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 __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./compilador-arm"), exports);
|
|
18
|
+
__exportStar(require("./verificador-toolchain"), exports);
|
|
19
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../fontes/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,mDAAiC;AACjC,0DAAwC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../fontes/interfaces/index.ts"],"names":[],"mappings":"AAAA,cAAc,+BAA+B,CAAC;AAC9C,cAAc,kCAAkC,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
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 __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./opcoes-compilacao-interface"), exports);
|
|
18
|
+
__exportStar(require("./resultado-compilacao-interface"), exports);
|
|
19
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../fontes/interfaces/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,gEAA8C;AAC9C,mEAAiD"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface OpcaoesCompilacao {
|
|
2
|
+
/** Caminho para o arquivo .delegua de entrada. */
|
|
3
|
+
arquivoEntrada: string;
|
|
4
|
+
/** Nome do binário de saída (sem extensão). Padrão: nome do arquivo de entrada. */
|
|
5
|
+
nomeSaida?: string;
|
|
6
|
+
/** Plataforma alvo. Padrão: linux-arm. */
|
|
7
|
+
alvo?: 'linux-arm' | 'android';
|
|
8
|
+
/** Se verdadeiro, mantém os arquivos intermediários (.s, .o) após a compilação. */
|
|
9
|
+
manterTemporarios?: boolean;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=opcoes-compilacao-interface.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"opcoes-compilacao-interface.d.ts","sourceRoot":"","sources":["../../fontes/interfaces/opcoes-compilacao-interface.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,iBAAiB;IAC9B,kDAAkD;IAClD,cAAc,EAAE,MAAM,CAAC;IACvB,mFAAmF;IACnF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,0CAA0C;IAC1C,IAAI,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;IAC/B,mFAAmF;IACnF,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC/B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"opcoes-compilacao-interface.js","sourceRoot":"","sources":["../../fontes/interfaces/opcoes-compilacao-interface.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resultado-compilacao-interface.d.ts","sourceRoot":"","sources":["../../fontes/interfaces/resultado-compilacao-interface.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,mBAAmB;IAChC,OAAO,EAAE,OAAO,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,IAAI,CAAC,EAAE,MAAM,CAAC;CACjB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resultado-compilacao-interface.js","sourceRoot":"","sources":["../../fontes/interfaces/resultado-compilacao-interface.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export interface FerramentaToolchain {
|
|
2
|
+
nome: string;
|
|
3
|
+
comando: string;
|
|
4
|
+
obrigatoria: boolean;
|
|
5
|
+
plataformas: ('linux-arm' | 'android')[];
|
|
6
|
+
mensagemAjuda: string;
|
|
7
|
+
}
|
|
8
|
+
export interface ResultadoVerificacao {
|
|
9
|
+
sucesso: boolean;
|
|
10
|
+
ferramentasDisponiveis: FerramentaToolchain[];
|
|
11
|
+
ferramentasFaltando: FerramentaToolchain[];
|
|
12
|
+
avisos: FerramentaToolchain[];
|
|
13
|
+
}
|
|
14
|
+
export declare function verificarToolchain(alvo?: 'linux-arm' | 'android'): ResultadoVerificacao;
|
|
15
|
+
//# sourceMappingURL=verificador-toolchain.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verificador-toolchain.d.ts","sourceRoot":"","sources":["../fontes/verificador-toolchain.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,mBAAmB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,OAAO,CAAC;IACrB,WAAW,EAAE,CAAC,WAAW,GAAG,SAAS,CAAC,EAAE,CAAC;IACzC,aAAa,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,oBAAoB;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,sBAAsB,EAAE,mBAAmB,EAAE,CAAC;IAC9C,mBAAmB,EAAE,mBAAmB,EAAE,CAAC;IAC3C,MAAM,EAAE,mBAAmB,EAAE,CAAC;CACjC;AAkDD,wBAAgB,kBAAkB,CAAC,IAAI,CAAC,EAAE,WAAW,GAAG,SAAS,GAAG,oBAAoB,CA0BvF"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.verificarToolchain = verificarToolchain;
|
|
4
|
+
const child_process_1 = require("child_process");
|
|
5
|
+
const FERRAMENTAS = [
|
|
6
|
+
{
|
|
7
|
+
nome: 'arm-linux-gnueabihf-as (GNU Assembler ARM)',
|
|
8
|
+
comando: 'arm-linux-gnueabihf-as',
|
|
9
|
+
obrigatoria: true,
|
|
10
|
+
plataformas: ['linux-arm'],
|
|
11
|
+
mensagemAjuda: 'Necessário para montar o assembly ARM gerado. ' +
|
|
12
|
+
'Linux: apt install gcc-arm-linux-gnueabihf binutils-arm-linux-gnueabihf',
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
nome: 'arm-linux-gnueabihf-ld (GNU Linker ARM)',
|
|
16
|
+
comando: 'arm-linux-gnueabihf-ld',
|
|
17
|
+
obrigatoria: true,
|
|
18
|
+
plataformas: ['linux-arm'],
|
|
19
|
+
mensagemAjuda: 'Necessário para linkar o objeto ARM no Linux. ' +
|
|
20
|
+
'Linux: apt install binutils-arm-linux-gnueabihf',
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
nome: 'arm-linux-androideabi-as (NDK Assembler)',
|
|
24
|
+
comando: 'arm-linux-androideabi-as',
|
|
25
|
+
obrigatoria: true,
|
|
26
|
+
plataformas: ['android'],
|
|
27
|
+
mensagemAjuda: 'Necessário para montar o assembly Android/ARM. ' +
|
|
28
|
+
'Instale o Android NDK e adicione o diretório toolchain ao PATH.',
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
nome: 'arm-linux-androideabi-ld (NDK Linker)',
|
|
32
|
+
comando: 'arm-linux-androideabi-ld',
|
|
33
|
+
obrigatoria: true,
|
|
34
|
+
plataformas: ['android'],
|
|
35
|
+
mensagemAjuda: 'Necessário para linkar o objeto Android/ARM. ' +
|
|
36
|
+
'Instale o Android NDK e adicione o diretório toolchain ao PATH.',
|
|
37
|
+
},
|
|
38
|
+
];
|
|
39
|
+
function verificarFerramenta(ferramenta) {
|
|
40
|
+
try {
|
|
41
|
+
(0, child_process_1.execSync)(`${ferramenta.comando} --version`, { stdio: 'pipe' });
|
|
42
|
+
return true;
|
|
43
|
+
}
|
|
44
|
+
catch (_a) {
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
function verificarToolchain(alvo) {
|
|
49
|
+
const plataforma = alvo !== null && alvo !== void 0 ? alvo : 'linux-arm';
|
|
50
|
+
const ferramentasDisponiveis = [];
|
|
51
|
+
const ferramentasFaltando = [];
|
|
52
|
+
const avisos = [];
|
|
53
|
+
for (const ferramenta of FERRAMENTAS) {
|
|
54
|
+
if (!ferramenta.plataformas.includes(plataforma)) {
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
if (verificarFerramenta(ferramenta)) {
|
|
58
|
+
ferramentasDisponiveis.push(ferramenta);
|
|
59
|
+
}
|
|
60
|
+
else if (ferramenta.obrigatoria) {
|
|
61
|
+
ferramentasFaltando.push(ferramenta);
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
avisos.push(ferramenta);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return {
|
|
68
|
+
sucesso: ferramentasFaltando.length === 0,
|
|
69
|
+
ferramentasDisponiveis,
|
|
70
|
+
ferramentasFaltando,
|
|
71
|
+
avisos,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=verificador-toolchain.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verificador-toolchain.js","sourceRoot":"","sources":["../fontes/verificador-toolchain.ts"],"names":[],"mappings":";;AAiEA,gDA0BC;AA3FD,iDAAyC;AAiBzC,MAAM,WAAW,GAA0B;IACvC;QACI,IAAI,EAAE,4CAA4C;QAClD,OAAO,EAAE,wBAAwB;QACjC,WAAW,EAAE,IAAI;QACjB,WAAW,EAAE,CAAC,WAAW,CAAC;QAC1B,aAAa,EACT,gDAAgD;YAChD,yEAAyE;KAChF;IACD;QACI,IAAI,EAAE,yCAAyC;QAC/C,OAAO,EAAE,wBAAwB;QACjC,WAAW,EAAE,IAAI;QACjB,WAAW,EAAE,CAAC,WAAW,CAAC;QAC1B,aAAa,EACT,gDAAgD;YAChD,iDAAiD;KACxD;IACD;QACI,IAAI,EAAE,0CAA0C;QAChD,OAAO,EAAE,0BAA0B;QACnC,WAAW,EAAE,IAAI;QACjB,WAAW,EAAE,CAAC,SAAS,CAAC;QACxB,aAAa,EACT,iDAAiD;YACjD,iEAAiE;KACxE;IACD;QACI,IAAI,EAAE,uCAAuC;QAC7C,OAAO,EAAE,0BAA0B;QACnC,WAAW,EAAE,IAAI;QACjB,WAAW,EAAE,CAAC,SAAS,CAAC;QACxB,aAAa,EACT,+CAA+C;YAC/C,iEAAiE;KACxE;CACJ,CAAC;AAEF,SAAS,mBAAmB,CAAC,UAA+B;IACxD,IAAI,CAAC;QACD,IAAA,wBAAQ,EAAC,GAAG,UAAU,CAAC,OAAO,YAAY,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;QAC/D,OAAO,IAAI,CAAC;IAChB,CAAC;IAAC,WAAM,CAAC;QACL,OAAO,KAAK,CAAC;IACjB,CAAC;AACL,CAAC;AAED,SAAgB,kBAAkB,CAAC,IAA8B;IAC7D,MAAM,UAAU,GAAG,IAAI,aAAJ,IAAI,cAAJ,IAAI,GAAI,WAAW,CAAC;IACvC,MAAM,sBAAsB,GAA0B,EAAE,CAAC;IACzD,MAAM,mBAAmB,GAA0B,EAAE,CAAC;IACtD,MAAM,MAAM,GAA0B,EAAE,CAAC;IAEzC,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE,CAAC;QACnC,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;YAC/C,SAAS;QACb,CAAC;QAED,IAAI,mBAAmB,CAAC,UAAU,CAAC,EAAE,CAAC;YAClC,sBAAsB,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC5C,CAAC;aAAM,IAAI,UAAU,CAAC,WAAW,EAAE,CAAC;YAChC,mBAAmB,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACzC,CAAC;aAAM,CAAC;YACJ,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC5B,CAAC;IACL,CAAC;IAED,OAAO;QACH,OAAO,EAAE,mBAAmB,CAAC,MAAM,KAAK,CAAC;QACzC,sBAAsB;QACtB,mBAAmB;QACnB,MAAM;KACT,CAAC;AACN,CAAC"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import * as fs from 'fs';
|
|
2
|
+
import * as path from 'path';
|
|
3
|
+
import { execSync } from 'child_process';
|
|
4
|
+
import { Lexador, AvaliadorSintatico, TradutorAssemblyARM } from '@designliquido/delegua';
|
|
5
|
+
|
|
6
|
+
import { verificarToolchain } from './verificador-toolchain';
|
|
7
|
+
import { OpcaoesCompilacao, ResultadoCompilacao } from './interfaces';
|
|
8
|
+
|
|
9
|
+
export class CompiladorARM {
|
|
10
|
+
async compilar(opcoes: OpcaoesCompilacao): Promise<ResultadoCompilacao> {
|
|
11
|
+
const alvo = opcoes.alvo ?? 'linux-arm';
|
|
12
|
+
|
|
13
|
+
const resultado = verificarToolchain(alvo);
|
|
14
|
+
if (!resultado.sucesso) {
|
|
15
|
+
const nomes = resultado.ferramentasFaltando
|
|
16
|
+
.map((f) => ` • ${f.nome}: ${f.mensagemAjuda}`)
|
|
17
|
+
.join('\n');
|
|
18
|
+
return {
|
|
19
|
+
sucesso: false,
|
|
20
|
+
erro: `Ferramentas obrigatórias não encontradas no PATH:\n${nomes}`,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const { arquivoEntrada, nomeSaida, manterTemporarios } = opcoes;
|
|
25
|
+
const nomeBase = path.basename(arquivoEntrada, path.extname(arquivoEntrada));
|
|
26
|
+
const nomeBinario = nomeSaida || nomeBase;
|
|
27
|
+
const diretorioSaida = path.dirname(arquivoEntrada);
|
|
28
|
+
const caminhoBinario = path.join(diretorioSaida, nomeBinario);
|
|
29
|
+
const arquivosTemporarios: string[] = [];
|
|
30
|
+
|
|
31
|
+
const prefixoToolchain = alvo === 'android' ? 'arm-linux-androideabi' : 'arm-linux-gnueabihf';
|
|
32
|
+
|
|
33
|
+
try {
|
|
34
|
+
// 1. Ler e lexar o fonte
|
|
35
|
+
const conteudo = fs.readFileSync(arquivoEntrada, 'utf-8');
|
|
36
|
+
const linhas = conteudo.split('\n');
|
|
37
|
+
|
|
38
|
+
const lexador = new Lexador();
|
|
39
|
+
const resultadoLex = lexador.mapear(linhas, -1);
|
|
40
|
+
|
|
41
|
+
if (resultadoLex.erros && resultadoLex.erros.length > 0) {
|
|
42
|
+
const msgs = resultadoLex.erros.map((e: any) => String(e)).join('\n');
|
|
43
|
+
return { sucesso: false, erro: `Erros léxicos:\n${msgs}` };
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// 2. Analisar sintaticamente
|
|
47
|
+
const avaliador = new AvaliadorSintatico();
|
|
48
|
+
const resultadoParse = await avaliador.analisar(resultadoLex, -1);
|
|
49
|
+
|
|
50
|
+
if (resultadoParse.erros && resultadoParse.erros.length > 0) {
|
|
51
|
+
const msgs = resultadoParse.erros.map((e: any) => String(e)).join('\n');
|
|
52
|
+
return { sucesso: false, erro: `Erros sintáticos:\n${msgs}` };
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// 3. Traduzir para assembly ARM (GAS)
|
|
56
|
+
const tradutor = new TradutorAssemblyARM(alvo);
|
|
57
|
+
const assembly = tradutor.traduzir(resultadoParse.declaracoes);
|
|
58
|
+
|
|
59
|
+
// 4. Gravar arquivo .s
|
|
60
|
+
const caminhoAsm = path.join(diretorioSaida, `${nomeBase}.s`);
|
|
61
|
+
fs.writeFileSync(caminhoAsm, assembly, 'utf-8');
|
|
62
|
+
arquivosTemporarios.push(caminhoAsm);
|
|
63
|
+
|
|
64
|
+
// 5. Montar com GNU Assembler (cross-assembler para ARM)
|
|
65
|
+
const caminhoObj = path.join(diretorioSaida, `${nomeBase}.o`);
|
|
66
|
+
execSync(`${prefixoToolchain}-as "${caminhoAsm}" -o "${caminhoObj}"`, { stdio: 'pipe' });
|
|
67
|
+
arquivosTemporarios.push(caminhoObj);
|
|
68
|
+
|
|
69
|
+
// 6. Linkar
|
|
70
|
+
execSync(`${prefixoToolchain}-ld "${caminhoObj}" -o "${caminhoBinario}"`, { stdio: 'pipe' });
|
|
71
|
+
|
|
72
|
+
// 7. Limpar temporários
|
|
73
|
+
if (!manterTemporarios) {
|
|
74
|
+
for (const arquivo of arquivosTemporarios) {
|
|
75
|
+
if (fs.existsSync(arquivo)) {
|
|
76
|
+
fs.unlinkSync(arquivo);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return { sucesso: true, caminhoBinario };
|
|
82
|
+
} catch (erro: any) {
|
|
83
|
+
if (!manterTemporarios) {
|
|
84
|
+
for (const arquivo of arquivosTemporarios) {
|
|
85
|
+
if (fs.existsSync(arquivo)) {
|
|
86
|
+
fs.unlinkSync(arquivo);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const mensagem =
|
|
92
|
+
erro.stderr?.toString().trim() ||
|
|
93
|
+
erro.stdout?.toString().trim() ||
|
|
94
|
+
erro.message ||
|
|
95
|
+
String(erro);
|
|
96
|
+
|
|
97
|
+
return { sucesso: false, erro: mensagem };
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
package/fontes/ilc.ts
ADDED
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import * as path from 'path';
|
|
3
|
+
import * as fs from 'fs';
|
|
4
|
+
|
|
5
|
+
import { CompiladorARM } from './compilador-arm';
|
|
6
|
+
import { verificarToolchain } from './verificador-toolchain';
|
|
7
|
+
|
|
8
|
+
const CORES = {
|
|
9
|
+
reset: '\x1b[0m',
|
|
10
|
+
verde: '\x1b[32m',
|
|
11
|
+
amarelo: '\x1b[33m',
|
|
12
|
+
azul: '\x1b[34m',
|
|
13
|
+
magenta: '\x1b[35m',
|
|
14
|
+
ciano: '\x1b[36m',
|
|
15
|
+
vermelho: '\x1b[31m',
|
|
16
|
+
negrito: '\x1b[1m',
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const LOGO = `
|
|
20
|
+
╔══════════════════════════════════════════════════════════════════╗
|
|
21
|
+
║ ║
|
|
22
|
+
║ ██████╗ ███████╗██╗ ███████╗ ██████╗ ██╗ ██╗ █████╗ ║
|
|
23
|
+
║ ██╔══██╗██╔════╝██║ ██╔════╝██╔════╝ ██║ ██║██╔══██╗ ║
|
|
24
|
+
║ ██║ ██║█████╗ ██║ █████╗ ██║ ███╗██║ ██║███████║ ║
|
|
25
|
+
║ ██║ ██║██╔══╝ ██║ ██╔══╝ ██║ ██║██║ ██║██╔══██║ ║
|
|
26
|
+
║ ██████╔╝███████╗███████╗███████╗╚██████╔╝╚██████╔╝██║ ██║ ║
|
|
27
|
+
║ ╚═════╝ ╚══════╝╚══════╝╚══════╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝ ║
|
|
28
|
+
║ ║
|
|
29
|
+
║ █████╗ ██████╗ ███╗ ███╗ ║
|
|
30
|
+
║ ██╔══██╗██╔══██╗████╗ ████║ ║
|
|
31
|
+
║ ███████║██████╔╝██╔████╔██║ ║
|
|
32
|
+
║ ██╔══██║██╔══██╗██║╚██╔╝██║ ║
|
|
33
|
+
║ ██║ ██║██║ ██║██║ ╚═╝ ██║ ║
|
|
34
|
+
║ ╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═╝ ║
|
|
35
|
+
║ ║
|
|
36
|
+
║ Compilador Delégua → GAS → Nativo ARM ║
|
|
37
|
+
╚══════════════════════════════════════════════════════════════════╝
|
|
38
|
+
`;
|
|
39
|
+
|
|
40
|
+
function logEtapa(etapa: string) {
|
|
41
|
+
console.log(`\n${CORES.ciano}${CORES.negrito}▶ ${etapa}${CORES.reset}`);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function logSucesso(mensagem: string) {
|
|
45
|
+
console.log(`${CORES.verde} ✓ ${mensagem}${CORES.reset}`);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function logInfo(mensagem: string) {
|
|
49
|
+
console.log(`${CORES.azul} ℹ ${mensagem}${CORES.reset}`);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function logAviso(mensagem: string) {
|
|
53
|
+
console.log(`${CORES.amarelo} ⚠ ${mensagem}${CORES.reset}`);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function logErro(mensagem: string) {
|
|
57
|
+
console.log(`${CORES.vermelho} ✗ ${mensagem}${CORES.reset}`);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function exibirAjuda() {
|
|
61
|
+
console.log(`${CORES.amarelo}Uso:${CORES.reset}`);
|
|
62
|
+
console.log(` npx delegua-arm <arquivo.delegua>`);
|
|
63
|
+
console.log('');
|
|
64
|
+
console.log(`${CORES.amarelo}Opções:${CORES.reset}`);
|
|
65
|
+
console.log(` -o <nome> Nome do binário de saída`);
|
|
66
|
+
console.log(` --alvo <linux-arm|android> Plataforma alvo (padrão: linux-arm)`);
|
|
67
|
+
console.log(` --manter-temporarios Não remove arquivos .s e .o após compilar`);
|
|
68
|
+
console.log('');
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function verificarEReportarToolchain(alvo?: 'linux-arm' | 'android'): boolean {
|
|
72
|
+
logEtapa('Verificando ferramentas do toolchain');
|
|
73
|
+
|
|
74
|
+
const resultado = verificarToolchain(alvo);
|
|
75
|
+
|
|
76
|
+
for (const ferramenta of resultado.ferramentasDisponiveis) {
|
|
77
|
+
logSucesso(`${ferramenta.nome} encontrado`);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
for (const ferramenta of resultado.avisos) {
|
|
81
|
+
logAviso(`${ferramenta.nome} não encontrado (opcional)`);
|
|
82
|
+
logAviso(` ${ferramenta.mensagemAjuda}`);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
for (const ferramenta of resultado.ferramentasFaltando) {
|
|
86
|
+
logErro(`${ferramenta.nome} não encontrado`);
|
|
87
|
+
logErro(` ${ferramenta.mensagemAjuda}`);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
if (!resultado.sucesso) {
|
|
91
|
+
console.log('');
|
|
92
|
+
logErro('Compilação cancelada. Instale as ferramentas acima e tente novamente.');
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
return resultado.sucesso;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
async function principal() {
|
|
99
|
+
console.log(CORES.magenta + LOGO + CORES.reset);
|
|
100
|
+
|
|
101
|
+
const args = process.argv.slice(2);
|
|
102
|
+
|
|
103
|
+
if (args.length === 0) {
|
|
104
|
+
exibirAjuda();
|
|
105
|
+
process.exit(1);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
let arquivoEntrada = '';
|
|
109
|
+
let nomeSaida = '';
|
|
110
|
+
let alvo: 'linux-arm' | 'android' | undefined;
|
|
111
|
+
let manterTemporarios = false;
|
|
112
|
+
|
|
113
|
+
for (let i = 0; i < args.length; i++) {
|
|
114
|
+
if (args[i] === '-o' && args[i + 1]) {
|
|
115
|
+
nomeSaida = args[++i];
|
|
116
|
+
} else if (args[i] === '--alvo' && args[i + 1]) {
|
|
117
|
+
const valor = args[++i];
|
|
118
|
+
if (valor !== 'linux-arm' && valor !== 'android') {
|
|
119
|
+
logErro(`Alvo inválido: "${valor}". Use linux-arm ou android.`);
|
|
120
|
+
process.exit(1);
|
|
121
|
+
}
|
|
122
|
+
alvo = valor;
|
|
123
|
+
} else if (args[i] === '--manter-temporarios') {
|
|
124
|
+
manterTemporarios = true;
|
|
125
|
+
} else if (!arquivoEntrada) {
|
|
126
|
+
arquivoEntrada = args[i];
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
if (!arquivoEntrada) {
|
|
131
|
+
logErro('Arquivo de entrada não especificado.');
|
|
132
|
+
exibirAjuda();
|
|
133
|
+
process.exit(1);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
if (!fs.existsSync(arquivoEntrada)) {
|
|
137
|
+
logErro(`Arquivo não encontrado: ${arquivoEntrada}`);
|
|
138
|
+
process.exit(1);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
if (!verificarEReportarToolchain(alvo)) {
|
|
142
|
+
process.exit(1);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
logEtapa('Iniciando compilação');
|
|
146
|
+
logInfo(`Arquivo: ${arquivoEntrada}`);
|
|
147
|
+
if (alvo) logInfo(`Alvo: ${alvo}`);
|
|
148
|
+
|
|
149
|
+
const compilador = new CompiladorARM();
|
|
150
|
+
const resultado = await compilador.compilar({
|
|
151
|
+
arquivoEntrada,
|
|
152
|
+
nomeSaida,
|
|
153
|
+
alvo,
|
|
154
|
+
manterTemporarios,
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
if (!resultado.sucesso) {
|
|
158
|
+
logErro('Erro durante a compilação:');
|
|
159
|
+
console.error(resultado.erro);
|
|
160
|
+
process.exit(1);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
console.log('');
|
|
164
|
+
console.log(`${CORES.verde}${CORES.negrito}════════════════════════════════════════════════════════════════${CORES.reset}`);
|
|
165
|
+
console.log(`${CORES.verde}${CORES.negrito} ✓ Compilação concluída com sucesso!${CORES.reset}`);
|
|
166
|
+
console.log(`${CORES.verde}${CORES.negrito}════════════════════════════════════════════════════════════════${CORES.reset}`);
|
|
167
|
+
console.log('');
|
|
168
|
+
logInfo(`Binário: ${CORES.negrito}${resultado.caminhoBinario}${CORES.reset}`);
|
|
169
|
+
logInfo(`Para executar: ${CORES.negrito}./${path.relative('.', resultado.caminhoBinario!)}${CORES.reset}`);
|
|
170
|
+
console.log('');
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
principal();
|
package/fontes/index.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export interface OpcaoesCompilacao {
|
|
2
|
+
/** Caminho para o arquivo .delegua de entrada. */
|
|
3
|
+
arquivoEntrada: string;
|
|
4
|
+
/** Nome do binário de saída (sem extensão). Padrão: nome do arquivo de entrada. */
|
|
5
|
+
nomeSaida?: string;
|
|
6
|
+
/** Plataforma alvo. Padrão: linux-arm. */
|
|
7
|
+
alvo?: 'linux-arm' | 'android';
|
|
8
|
+
/** Se verdadeiro, mantém os arquivos intermediários (.s, .o) após a compilação. */
|
|
9
|
+
manterTemporarios?: boolean;
|
|
10
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { execSync } from 'child_process';
|
|
2
|
+
|
|
3
|
+
export interface FerramentaToolchain {
|
|
4
|
+
nome: string;
|
|
5
|
+
comando: string;
|
|
6
|
+
obrigatoria: boolean;
|
|
7
|
+
plataformas: ('linux-arm' | 'android')[];
|
|
8
|
+
mensagemAjuda: string;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface ResultadoVerificacao {
|
|
12
|
+
sucesso: boolean;
|
|
13
|
+
ferramentasDisponiveis: FerramentaToolchain[];
|
|
14
|
+
ferramentasFaltando: FerramentaToolchain[];
|
|
15
|
+
avisos: FerramentaToolchain[];
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const FERRAMENTAS: FerramentaToolchain[] = [
|
|
19
|
+
{
|
|
20
|
+
nome: 'arm-linux-gnueabihf-as (GNU Assembler ARM)',
|
|
21
|
+
comando: 'arm-linux-gnueabihf-as',
|
|
22
|
+
obrigatoria: true,
|
|
23
|
+
plataformas: ['linux-arm'],
|
|
24
|
+
mensagemAjuda:
|
|
25
|
+
'Necessário para montar o assembly ARM gerado. ' +
|
|
26
|
+
'Linux: apt install gcc-arm-linux-gnueabihf binutils-arm-linux-gnueabihf',
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
nome: 'arm-linux-gnueabihf-ld (GNU Linker ARM)',
|
|
30
|
+
comando: 'arm-linux-gnueabihf-ld',
|
|
31
|
+
obrigatoria: true,
|
|
32
|
+
plataformas: ['linux-arm'],
|
|
33
|
+
mensagemAjuda:
|
|
34
|
+
'Necessário para linkar o objeto ARM no Linux. ' +
|
|
35
|
+
'Linux: apt install binutils-arm-linux-gnueabihf',
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
nome: 'arm-linux-androideabi-as (NDK Assembler)',
|
|
39
|
+
comando: 'arm-linux-androideabi-as',
|
|
40
|
+
obrigatoria: true,
|
|
41
|
+
plataformas: ['android'],
|
|
42
|
+
mensagemAjuda:
|
|
43
|
+
'Necessário para montar o assembly Android/ARM. ' +
|
|
44
|
+
'Instale o Android NDK e adicione o diretório toolchain ao PATH.',
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
nome: 'arm-linux-androideabi-ld (NDK Linker)',
|
|
48
|
+
comando: 'arm-linux-androideabi-ld',
|
|
49
|
+
obrigatoria: true,
|
|
50
|
+
plataformas: ['android'],
|
|
51
|
+
mensagemAjuda:
|
|
52
|
+
'Necessário para linkar o objeto Android/ARM. ' +
|
|
53
|
+
'Instale o Android NDK e adicione o diretório toolchain ao PATH.',
|
|
54
|
+
},
|
|
55
|
+
];
|
|
56
|
+
|
|
57
|
+
function verificarFerramenta(ferramenta: FerramentaToolchain): boolean {
|
|
58
|
+
try {
|
|
59
|
+
execSync(`${ferramenta.comando} --version`, { stdio: 'pipe' });
|
|
60
|
+
return true;
|
|
61
|
+
} catch {
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export function verificarToolchain(alvo?: 'linux-arm' | 'android'): ResultadoVerificacao {
|
|
67
|
+
const plataforma = alvo ?? 'linux-arm';
|
|
68
|
+
const ferramentasDisponiveis: FerramentaToolchain[] = [];
|
|
69
|
+
const ferramentasFaltando: FerramentaToolchain[] = [];
|
|
70
|
+
const avisos: FerramentaToolchain[] = [];
|
|
71
|
+
|
|
72
|
+
for (const ferramenta of FERRAMENTAS) {
|
|
73
|
+
if (!ferramenta.plataformas.includes(plataforma)) {
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (verificarFerramenta(ferramenta)) {
|
|
78
|
+
ferramentasDisponiveis.push(ferramenta);
|
|
79
|
+
} else if (ferramenta.obrigatoria) {
|
|
80
|
+
ferramentasFaltando.push(ferramenta);
|
|
81
|
+
} else {
|
|
82
|
+
avisos.push(ferramenta);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return {
|
|
87
|
+
sucesso: ferramentasFaltando.length === 0,
|
|
88
|
+
ferramentasDisponiveis,
|
|
89
|
+
ferramentasFaltando,
|
|
90
|
+
avisos,
|
|
91
|
+
};
|
|
92
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "delegua-arm",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "Compilador Delégua para binários ARM via GNU Assembler, sem LLVM.",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"bin": {
|
|
8
|
+
"delegua-arm": "./dist/ilc.js"
|
|
9
|
+
},
|
|
10
|
+
"author": "Leonel Sanches da Silva",
|
|
11
|
+
"license": "MIT",
|
|
12
|
+
"publishConfig": {
|
|
13
|
+
"access": "public",
|
|
14
|
+
"registry": "https://registry.npmjs.org"
|
|
15
|
+
},
|
|
16
|
+
"scripts": {
|
|
17
|
+
"empacotar": "yarn rimraf ./dist && yarn tsc",
|
|
18
|
+
"testes-unitarios": "yarn jest --coverage",
|
|
19
|
+
"executar": "yarn ts-node fontes/ilc.ts",
|
|
20
|
+
"prepublishOnly": "yarn empacotar"
|
|
21
|
+
},
|
|
22
|
+
"dependencies": {
|
|
23
|
+
"@designliquido/delegua": "*"
|
|
24
|
+
},
|
|
25
|
+
"devDependencies": {
|
|
26
|
+
"@types/jest": "^29.5.14",
|
|
27
|
+
"@types/node": "^22.9.0",
|
|
28
|
+
"jest": "^29.7.0",
|
|
29
|
+
"prettier": "^3.3.3",
|
|
30
|
+
"rimraf": "^6.1.3",
|
|
31
|
+
"ts-jest": "^29.2.5",
|
|
32
|
+
"ts-node": "^10.9.2",
|
|
33
|
+
"typescript": "^5.6.3"
|
|
34
|
+
}
|
|
35
|
+
}
|