Manual de Usuario — GoScript IDE
Proyecto 2 · Organización de Lenguajes y Compiladores 1
Universidad de San Carlos de Guatemala — Facultad de Ingeniería
Escuela de Ingeniería en Ciencias y Sistemas
Primer Semestre 2026
Autor: Mynor Cifuentes · Carné 201318644
Índice
- ¿Qué es GoScript?
- Instalación y primer uso
- Recorrido por el IDE
- Tu primer programa
- Variables y tipos
- Operadores
- Control de flujo
- Funciones
- Slices
- Structs
- Funciones embebidas
- Reportes
- Atajos de teclado
- Solución de problemas
- Limitaciones
1. ¿Qué es GoScript?
GoScript es un lenguaje de programación interpretado, fuertemente tipado e
inspirado en Go, creado para el segundo proyecto del curso. El IDE web te
permite:
- Escribir, editar y guardar archivos
.gst. - Ejecutar tu programa y ver la salida en una consola integrada.
- Inspeccionar errores léxicos, sintácticos y semánticos en una tabla.
- Revisar la tabla de símbolos generada durante la ejecución.
- Visualizar el árbol de sintaxis abstracta (AST) como un diagrama.
- Trabajar con varios archivos a la vez gracias al sistema de pestañas.
2. Instalación y primer uso
Requisitos
- Node.js 18 o superior (recomendado 20+).
- npm (viene con Node).
- Un navegador moderno (Chrome, Firefox, Edge, Safari).
Pasos
Abre dos terminales en la raíz del proyecto.
Terminal 1 — Backend:
1 | cd backend |
Verás el mensaje [GoScript] API escuchando en http://localhost:3001.
Terminal 2 — Frontend:
1 | cd frontend |
Vite te dará una URL, normalmente http://localhost:5173/. Ábrela en tu
navegador y deberías ver el IDE listo para usar.
Nota: la primera vez tarda un poco más porque
npm installdescarga
dependencias ynpm run devdel backend genera el parser con Jison.
3. Recorrido por el IDE
1 | ┌──────────────────────────────────────────────────────────────────┐ |
Zonas principales
- Barra superior: nombre del archivo activo (editable in-place) y los
botones Nuevo, Abrir, Guardar y Ejecutar. - Barra de pestañas: una por archivo abierto. Click izquierdo para
cambiar, click central o×para cerrar. El botón+agrega una nueva. - Editor: Monaco con resaltado de sintaxis Go, minimapa, números de
línea y autoindentación. - Panel lateral: cuatro vistas para inspeccionar el resultado de la
ejecución más reciente (Consola, Errores, Tabla de Símbolos, AST). - Pie: indicador de cantidad de pestañas, marca de “sin guardar” y URL
del API que está usando el frontend.
Pestaña sucia
Cuando una pestaña tiene cambios sin guardar, aparece un punto al lado del
nombre. Si intentas cerrarla o cerrar el navegador, el IDE pedirá
confirmación para evitar perder trabajo.
4. Tu primer programa
El IDE arranca con un archivo programa.gst que contiene:
1 | // Bienvenido a GoScript |
Pulsa ▶ Ejecutar (o haz click en el botón). En el panel Consola verás:
1 | Hola, GoScript! |
Importante: todo programa GoScript debe tener una función
main()
sin parámetros. Es el punto de entrada.
5. Variables y tipos
Tipos primitivos
| Tipo | Descripción | Ejemplos de literal |
|---|---|---|
int |
Entero con signo. | 0, 42, -7 |
float64 |
Número con decimales. | 3.14, 0.5, -2.0 |
string |
Texto entre comillas dobles. | "Hola", "línea 1\nlínea 2" |
bool |
Booleano. | true, false |
rune |
Carácter Unicode. | 'A', 'ñ', '\n' |
nil |
Ausencia de valor. | nil |
Declaraciones soportadas
GoScript admite tres estilos de declaración para que la sintaxis sea
flexible:
1 | func main() { |
Valor por defecto
Si declaras una variable con var x T sin valor:
| Tipo | Valor por defecto |
|---|---|
int, rune |
0 |
float64 |
0.0 |
string |
"" |
bool |
false |
| slice | nil |
| struct | nil |
Reglas de coerción al asignar
Sólo hay una promoción automática: int o rune → float64. Cualquier
otra mezcla de tipos al asignar produce un error semántico. Por ejemplo:
1 | var x float64 = 7 // OK: 7 (int) se promueve a 7.0 |
Para convertir entre tipos numéricos y strings usa los built-insstrconv.Atoi y strconv.ParseFloat (sección 11).
6. Operadores
Aritméticos
+, -, *, /, %. Reglas resumidas:
- Cualquier operación con
stringy otro tipo en+produce un string
(concatenación con conversión automática). - Si alguno de los operandos es
float64, el resultado esfloat64. int / intdainttruncado. Si quieresfloat64divide entre1.0
o convierte uno de los operandos.%solo funciona entreint.string * intrepite la cadena ("ab" * 3 = "ababab").- División y módulo entre cero generan error de ejecución.
Incremento y decremento
x++ y x-- son sentencias, no expresiones. Se permiten sobre cualquier
lvalue numérico (variables, slice[i], struct.campo).
Comparación
==, !=, <, <=, >, >=. Devuelven bool. Comparan numéricos entre
sí (con promoción automática), strings entre sí, booleanos entre sí, y nil
con cualquier referencia (slice/struct).
Lógicos
&&, ||, ! solo aplican a booleanos. && y || evalúan en
cortocircuito:
1 | if x != nil && x.activo { |
Asignación compuesta
+= y -= modifican un lvalue en su lugar:
1 | total := 0 |
Precedencia (de menor a mayor)
1 | || |
Usa paréntesis cuando dudes; el AST refleja exactamente lo que escribiste.
7. Control de flujo
if / else if / else
1 | if edad >= 18 { |
La condición debe ser un bool. No hay conversión automática.
switch
1 | switch dia { |
A diferencia de C, no hay fall-through: cada case termina implícitamente
después de ejecutar su cuerpo.
for (cuatro variantes)
1 | // 1) Infinito |
break, continue, return
breaksale delforoswitchenvolvente más cercano.continuesalta al siguiente ciclo delforenvolvente.returndevuelve de la función actual; con o sin valor según la firma.
Usar cualquiera de los tres fuera de su contexto válido produce un error
semántico.
8. Funciones
Declaración
1 | func sumar(a int, b int) int { |
Recursión
Las funciones pueden llamarse a sí mismas sin restricciones:
1 | func factorial(n int) int { |
Slices como argumento o retorno
1 | func duplicar(valores []int) []int { |
Reglas
- Cada función define un nuevo ámbito; sus parámetros se declaran como
variables locales. - El padre del entorno de una función es siempre el global; no se capturan
variables del ámbito del llamador. - Sólo se puede devolver un valor (o ninguno).
- Si una función con tipo de retorno termina sin
return, devolverá el
valor por defecto del tipo.
9. Slices
Un slice es una secuencia indexada y dinámica de elementos del mismo tipo.
Creación
1 | // Forma estándar: tipo seguido de los elementos |
Acceso, modificación y len
1 | fmt.Println(nums[0]) // 10 |
Slices multidimensionales
1 | matriz := [][]int{ |
El elemento abreviado
{1, 2, 3}dentro de un slice multidimensional
hereda el tipo del slice padre. La coma final en la última línea es
opcional pero permitida.
append
Agrega uno o más elementos al final y devuelve un nuevo slice:
1 | nums = append(nums, 40) |
Importante: append no muta el slice original; siempre asigna el resultado.
for-range
1 | for i, v := range nums { |
10. Structs
Los structs son tipos compuestos con campos nombrados, declarados a nivel
global (fuera de cualquier función).
Declaración
1 | struct Persona { |
El punto y coma al final de cada campo es opcional.
Instanciación
GoScript admite dos sintaxis:
1 | func main() { |
Lectura y mutación de campos
1 | fmt.Println(ana.nombre) // Ana |
Acceso a structs anidados
GoScript soporta cualquier nivel de anidamiento. Cada acceso intermedio
devuelve una referencia al sub-struct, por lo que las mutaciones se
reflejan correctamente en el padre:
1 | rojos.capitan.edad = 27 // se ve también en ana.edad |
11. Funciones embebidas
| Función | Descripción | Ejemplo |
|---|---|---|
fmt.Println(...) |
Imprime los argumentos separados por espacios y agrega \n. |
fmt.Println("x =", x) |
fmt.Print(...) |
Igual a Println pero sin salto de línea. |
fmt.Print("Cargando...") |
strconv.Atoi(s) |
Convierte un string a int. Devuelve 0 si falla. |
n := strconv.Atoi("42") |
strconv.ParseFloat(s) |
Convierte un string a float64. |
pi := strconv.ParseFloat("3.14") |
reflect.TypeOf(v) |
Devuelve el nombre del tipo de v como string. |
fmt.Println(reflect.TypeOf(3.14)) → float64 |
len(v) |
Longitud de un string o slice. | len("hola") → 4 |
append(s, x...) |
Devuelve un slice nuevo con los elementos agregados al final. | s = append(s, 1, 2, 3) |
slices.Index(s, x) |
Devuelve la posición de x en s, o -1. |
slices.Index([]int{2,4,6}, 4) → 1 |
strings.Join(s, sep) |
Une un []string usando el separador. |
strings.Join([]string{"a","b"}, "-") → "a-b" |
12. Reportes
Después de pulsar ▶ Ejecutar, el panel lateral muestra cuatro vistas:
Consola
Aquí aparece todo lo que tu programa escribe con fmt.Print y fmt.Println.
Errores
Tabla con todos los errores detectados, codificados por color:
- Rojo (Léxico) — el lexer encontró un carácter desconocido.
- Amarillo (Sintáctico) — el parser no pudo entender una construcción.
- Azul (Semántico) — el intérprete detectó una incoherencia en tiempo
de ejecución (variable no declarada, división entre cero, tipos
incompatibles, etc.).
Botón Descargar HTML: guarda un archivo autocontenido con el reporte.
Tabla de Símbolos
Lista todos los identificadores observados durante la ejecución (variables,
parámetros, funciones, structs) con su tipo, valor, ámbito y ubicación.
Botón Descargar HTML: guarda la tabla como archivo independiente.
AST
Diagrama interactivo del árbol de sintaxis abstracta producido por el
parser. Cada nodo está coloreado por categoría:
- Verde: declaraciones y literales.
- Azul: sentencias.
- Naranja: operadores.
- Morado: llamadas a función.
Botones Descargar SVG y Descargar DOT te permiten exportar el grafo
para incluirlo en informes o procesarlo con Graphviz fuera del IDE.
13. Atajos de teclado
| Acción | Mac | Windows / Linux |
|---|---|---|
| Guardar pestaña activa | ⌘ + S |
Ctrl + S |
| Nueva pestaña | ⌘ + N |
Ctrl + N |
| Cerrar pestaña activa | ⌘ + W |
Ctrl + W |
| Click central sobre pestaña | — | Cerrar |
Cuidado con
Ctrl + Shift + N: el IDE no captura esa combinación
porque algunos navegadores la usan para abrir ventana de incógnito.
14. Solución de problemas
“Error de red” al ejecutar
El frontend no pudo contactar al backend. Verifica que:
- El backend esté corriendo (
npm run deven la carpetabackend/). - La URL del API que aparece en el pie del IDE sea correcta.
- No haya un firewall bloqueando el puerto 3001.
“Error sintáctico cerca de X”
El parser encontró un token que no esperaba. Causas comunes:
- Olvidar el
()después del nombre de una función al llamarla. - Mezclar declaraciones con
:=y=(la primera declara, la segunda asigna). - Olvidar el tipo en una declaración estilo C: debe ser
int x = 5, nox int = 5. - Usar
{directamente como cuerpo delifsin la condición previa.
“La variable X no ha sido declarada”
Estás usando una variable que nunca se declaró en este ámbito ni en uno
padre. Recuerda que cada función tiene como padre el ámbito global, no
el del llamador.
“No se puede asignar T1 a T2”
Estás intentando una conversión que GoScript no hace automáticamente. La
única promoción implícita es int o rune → float64. Para todas las
demás usa strconv.Atoi, strconv.ParseFloat o concatenación con string.
El AST no se muestra
Verifica que la ejecución haya terminado sin errores fatales. Si hay un
error sintáctico el AST queda vacío. También revisa la consola del
navegador por si hubo un fallo al cargar la librería de Graphviz.
15. Limitaciones
GoScript es un subconjunto didáctico de Go. No soporta:
- Closures ni captura de variables externas en funciones.
- Funciones de orden superior (no se pueden pasar funciones como argumentos).
- Múltiples valores de retorno en una sola función.
- Maps (
map[K]V) ni canales (chan T). - Goroutines ni
select. - Punteros (
*T) ni operador&. - Interfaces ni métodos asociados a structs.
- Imports: los nombres
fmt,strconv, etc. son prefijos sintácticos
reservados, no módulos importables.
Si tu programa necesita alguna de estas características, deberás
adaptarlo a las construcciones disponibles en GoScript.
¿Necesitas más detalles sobre el lenguaje? Consulta también:
- GRAMATICA_BNF.md — gramática formal completa.
- MANUAL_TECNICO.md — arquitectura interna del intérprete.



