Um interpretador (simulador de execução) para programas JavaScript desenvolvido como projeto da disciplina Estruturas de Dados II na Universidade do Oeste Paulista (UNOESTE).
Este projeto implementa um interpretador completo para um subconjunto da linguagem JavaScript, capaz de executar programas passo a passo com visualização da memória RAM e controle de escopo através de estruturas de dados dinâmicas.
- Execução passo a passo: Navegação linha por linha com visualização da linha atual
- Gerenciamento de memória: Pilha dinâmica para variáveis e controle de escopo
- Interface visual: Tela do interpretador com destaque da linha em execução
- Controles interativos:
F7
- Abrir arquivo JavaScriptF8
- Executar programaF9
- Visualizar memória RAMF10
- Exibir tela de saídaENTER
- Executar linha atual e avançar
O interpretador assume que o código JavaScript está correto e não realiza verificação de erros.
- Não há tratamento de erros: O interpretador executa o código sem validar sintaxe ou semântica
- Código deve estar correto: Programas com erros podem causar comportamento inesperado
- Responsabilidade do programador: Garantir que o código está sintaticamente correto antes da execução
- Foco na execução: O objetivo é simular a execução, não detectar erros de programação
pPrograma → [300] → function → calcula → ( → x → y → )
↓
[312] → return → x → + → y
↓
[324] → fim-func
⋮
┌────┬─────────────┬────────┬──────────┐
│ & │identificador│ valor │ ponteiro │
├────┼─────────────┼────────┼──────────┤
│120 │ y │ 10 │ NULL │
│116 │ x │ 5 │ NULL │
│112 │ [endereço] │ - │ [372] │
│108 │ c │ 0 │ NULL │
│104 │ b │ 10 │ NULL │
│100 │ a │ 5 │ NULL │
└────┴─────────────┴────────┴──────────┘
Sistema de resolução de expressões com prioridades utilizando union para diferentes tipos de nodos:
- V (Value): Nodo terminal com valor
- O (Operator): Nodo com operador aritmético
- F (Function): Nodo com função matemática
- Declaração de funções com parâmetros
- Chamadas de função com passagem por valor
- Retorno de valores com
return
- Funções aninhadas
- Declaração com
let
econst
- Atribuição e reatribuição
- Escopo local e global
Aritméticos | Comparação | Lógicos |
---|---|---|
+ - * / |
== != |
&& ` |
% ** |
> < >= <= |
if (condição) {
comando(s);
} else if (condição) {
comando(s);
} else {
comando(s);
}
// While
while (condição) {
comando(s);
}
// Do-While
do {
comando(s);
} while (condição);
// For
for (let i = 0; i < 10; i++) {
comando(s);
}
let array = ['oi', 2.0, 5, [10, 20]];
console.log(array[0]); // oi
console.log(array[3][1]); // 20
// Métodos suportados
array.push(elemento); // Adicionar ao final
array.pop(); // Remover do final
array.unshift(elemento); // Adicionar ao início
array.shift(); // Remover do início
array.sort(); // Ordenar
array.length; // Tamanho
console.log()
- Saída de dadosconsole.table()
- Exibição tabularMath.sqrt()
- Raiz quadradaMath.abs()
- Valor absolutoparseInt()
- Conversão para inteirotoString()
- Conversão para string
InterpretadorDeJS/
├── README.md # Este arquivo
├── src/ # Código fonte
│ ├── main.c # Função principal
│ ├── parser.c # Analisador léxico/sintático
│ ├── interpreter.c # Motor de interpretação
│ ├── memory.c # Gerenciamento de memória
│ ├── expressions.c # Avaliação de expressões
│ └── structures/ # Estruturas de dados
│ ├── lista.c # Lista encadeada
│ ├── pilha.c # Pilha dinâmica
│ └── generalizada.c # Lista generalizada
├── tests/ # Programas de teste
│ ├── exemplo1.js # Função básica
│ ├── exemplo2.js # Laços while
│ ├── exemplo3.js # Laços for
│ ├── exemplo4.js # Funções matemáticas
│ └── exemplo5.js # Arrays e busca
├── docs/ # Documentação
│ └── estruturas.docx # Desenho das estruturas
└── Makefile # Compilação
- Compilador GCC
- Sistema operacional Linux/Unix ou Windows com MinGW
# Clone o repositório
git clone <url-do-repositorio>
cd InterpretadorDeJS
# Compile o projeto
make
# Ou compile manualmente
gcc -o interpretador src/*.c src/structures/*.c -lm
# Execute o interpretador
./interpretador
# Na interface:
# F7 - Selecione um arquivo .js para carregar
# F8 - Inicie a execução
# ENTER - Execute linha por linha
# F9 - Visualize a memória RAM
# F10 - Veja a saída do console.log()
function calcula(x, y) {
return x + y;
}
let a = 5;
let b = 10;
let c = calcula(a, b);
console.log("Resultado:", c);
function ordenarFrutas() {
let frutas = ['laranja', 'banana', 'abacaxi'];
frutas.sort();
console.log(frutas);
console.log("Tamanho:", frutas.length);
}
ordenarFrutas();
function verificaIdade(idade) {
if (idade >= 18) {
console.log("Maior de idade");
} else {
console.log("Menor de idade");
}
}
verificaIdade(20);
┌┤ C:\prog1.js ├────────────────────────────────┐
│function calcula(x, y) │
│{ │
│ return x + y; │
│} │
│let a = 5; │
│let b = 10; │
│let c = 0; │
│c = calcula(a, b); __________________________ │ ← Linha atual
│console.log(a, b, c); │
│a = calcula(7, a+b+c); │
│console.log("7", a+b+c, a); │
│c = calcula(a*b, a/b); │
│console.log(a*b, a/b, c); │
│a = calcula(b, b+b); │
│let msg = 'resultado = '; │
│console.log(msg, a, b, c); │
└───────────────────────────────────────────────┘
F7-Abrir F8-Executar F9-Memória RAM F10-Tela
O projeto inclui uma suíte completa de testes cobrindo:
- Exemplo 1: Chamadas de função e escopo
- Exemplo 2: Estruturas de repetição while
- Exemplo 3: Estruturas de repetição for
- Exemplo 4: Funções matemáticas e expressões
- Exemplo 5: Manipulação de arrays e estruturas condicionais
Execute os testes:
make test
# ou
./interpretador tests/exemplo1.js
./interpretador tests/exemplo2.js
# ... etc
O código JavaScript é parseado em uma estrutura de Lista de Listas, onde:
- Lista vertical: representa as linhas do programa
- Lista horizontal: contém os tokens de cada linha
- Pilha dinâmica: Gerencia variáveis e escopo
- Heap: Armazena ponteiros para linhas de execução
- Union structures: Suporte a múltiplos tipos de dados
Sistema baseado em Lista Generalizada que:
- Constrói árvore de expressão respeitando precedência
- Resolve operações "podando" nodos da lista
- Utiliza duas pilhas auxiliares (valores e operadores)
- Program Counter: Ponteiro para linha atual
- Call Stack: Gerencia chamadas de função
- Scope Chain: Controla visibilidade de variáveis
- Sem bibliotecas prontas: Implementação from scratch
- Sem strtok(): Parser customizado para tokenização
- Estruturas próprias: Listas, pilhas e árvores implementadas manualmente
- Uso de union: Para suporte a tipos heterogêneos nos nodos
Disciplina: Estruturas de Dados II
Professor: Francisco Assis da Silva
Instituição: UNOESTE - Universidade do Oeste Paulista
- Código-fonte completo
- Programas JavaScript de teste
- Documentação das estruturas (estruturas.docx)
- Apresentação em dupla
- Estruturas de Dados e Algoritmos em C
Este é um projeto acadêmico. Para melhorias ou correções:
- Fork o repositório
- Crie uma branch para sua feature
- Commit suas mudanças
- Push para a branch
- Abra um Pull Request
⚡ Um interpretador JavaScript completo implementado com estruturas de dados fundamentais!