Loading...

Manual Técnico — Intérprete GoScript

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

  1. Resumen
  2. Arquitectura general
  3. Backend: API e intérprete
  4. Análisis léxico y sintáctico (Jison)
  5. Árbol de Sintaxis Abstracta (AST)
  6. Sistema de tipos y valores en tiempo de ejecución
  7. Operadores y reglas de coerción implícita
  8. Intérprete (recorrido del AST)
  9. Tabla de símbolos y manejo de ámbitos
  10. Manejo de errores
  11. Funciones embebidas (built-ins)
  12. Generación de reportes
  13. Frontend: IDE web
  14. Compilación y despliegue
  15. Limitaciones conocidas

1. Resumen

GoScript es un lenguaje interpretado, fuertemente tipado, inspirado en Go, diseñado
como ejercicio académico del curso. El proyecto entrega:

  • Un intérprete que recibe código fuente .gst y produce salida estándar,
    errores léxicos/sintácticos/semánticos, una tabla de símbolos y un AST.
  • Un API HTTP (POST /api/run) que envuelve al intérprete y devuelve los
    reportes ya formateados.
  • Un IDE web con editor Monaco, múltiples pestañas, persistencia local y
    visualización del AST con Graphviz.

El código está dividido en dos paquetes Node.js independientes:

Paquete Tecnología Puerto Carpeta
Backend Node.js + Express + TypeScript + Jison 3001 backend/
Frontend React + Vite + TypeScript + Monaco 5173 frontend/

2. Arquitectura general

Diagrama de capas

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
┌──────────────────────────────────────────────────────────────────┐
│ IDE web (frontend/) │
│ React · Monaco · @viz-js/viz · localStorage · fetch │
└──────────────────────────────┬───────────────────────────────────┘
│ HTTP JSON (POST /api/run)

┌──────────────────────────────────────────────────────────────────┐
│ API Express (backend/src/server.ts) │
└──────────────────────────────┬───────────────────────────────────┘

┌──────────────────────────────────────────────────────────────────┐
│ runner.ts (orquestador) │
└──────┬──────────────┬─────────────┬─────────────┬────────────────┘
▼ ▼ ▼ ▼
parser.ts Interpreter astDot.ts symbolsHtml.ts
(Jison + (recorre el (Graphviz (tabla HTML
helpers) AST) DOT) de símbolos)


generated/parser.js ← generado por `jison src/grammar/goscript.jison`

Carpetas del backend

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
backend/src/
├── server.ts ← Express + endpoints /api/health, /api/run
├── interpreter/
│ ├── runner.ts ← punto de entrada de alto nivel
│ └── Interpreter.ts ← evaluador del AST
├── grammar/
│ ├── goscript.jison ← gramática léxica + sintáctica
│ ├── parser.ts ← wrapper tipado del parser generado
│ ├── lexer-helpers.ts ← parseString, parseRune (escapes)
│ └── generated/parser.js ← producto de `npm run build:grammar`
├── ast/
│ ├── nodes.ts ← interfaces de los nodos del AST
│ └── types.ts ← TypeRef y utilidades de tipos
├── runtime/
│ ├── values.ts ← GValue, constructores, formatValue
│ └── operators.ts ← opAdd, opSub, opEq, … con coerciones
├── symbols/
│ └── Environment.ts ← Environment + SymbolTable
├── errors/
│ └── ErrorReporter.ts ← colector de errores Léx/Sint/Sem
├── builtins/
│ └── index.ts ← fmt.*, strconv.*, reflect.*, len, append, …
└── reports/
├── astDot.ts ← AST → DOT (Graphviz)
├── symbolsHtml.ts ← tabla de símbolos → HTML
└── errorsHtml.ts ← lista de errores → HTML

Carpetas del frontend

1
2
3
4
5
frontend/src/
├── App.tsx ← IDE completo (multi-pestaña, paneles, fetch al API)
├── App.css ← estilos del IDE
├── main.tsx ← bootstrap React
└── index.css ← reset y estilos base

3. Backend: API e intérprete

3.1. Endpoints HTTP

backend/src/server.ts expone dos rutas:

Método Ruta Descripción
GET /api/health Sondeo simple. Devuelve { ok, service, version }.
POST /api/run Recibe { source: string } y devuelve el resultado de ejecutar el código.

Respuesta de /api/run (interfaz InterpretResult en runner.ts):

1
2
3
4
5
6
7
8
9
10
{
ok: true,
output: string, // salida estándar del programa
errors: GoScriptError[], // errores léx/sint/sem
ast: Program | null, // AST completo (o null si falló el parser)
symbols: SymbolInfo[], // tabla de símbolos serializable
astDot: string, // grafo Graphviz en formato DOT
symbolsHtml: string, // reporte HTML autocontenido
errorsHtml: string // reporte HTML autocontenido
}

3.2. Flujo de ejecución (runner.ts → interpret())

  1. Crea un ErrorReporter vacío.
  2. Llama parseGoScript(source, reporter) que:
    • Construye el parser Jison.
    • Inyecta parseString y parseRune en parser.yy (escapes de strings y runes).
    • Sustituye los handlers de error léxico/sintáctico para que escriban en el
      reporter con línea y columna humanas (1-based).
  3. Si el parser falla, devuelve un resultado vacío con la lista de errores.
  4. Si tiene éxito, instancia Interpreter y llama interp.run(ast).
  5. Genera los tres reportes (astDot, symbolsHtml, errorsHtml) y devuelve
    todo junto.
  6. sanitizeSymbols convierte los valores no serializables a string para que
    la respuesta JSON nunca falle.

4. Análisis léxico y sintáctico (Jison)

El archivo backend/src/grammar/goscript.jison define en un único archivo:

  • La sección %lex con las reglas léxicas.
  • La sección de gramática con sus acciones semánticas que construyen el AST.

4.1. Tokens léxicos

Categoría Tokens
Palabras reservadas func var if else for switch case default break continue return struct range nil true false int float64 string bool rune
Literales INT_LIT, FLOAT_LIT, STRING_LIT, RUNE_LIT
Identificadores IDENT
Operadores := += -= ++ -- == != <= >= && || = < > + - * / % !
Delimitadores ( ) { } [ ] , ; : .
Especiales <<EOF>>, LEXICAL_ERROR (cualquier caracter no reconocido)

4.2. Comentarios

  • Línea: // hasta fin de línea
  • Bloque: /* … */ (no anidados, soporta multilínea).

4.3. Escapes en strings y runes

lexer-helpers.ts maneja: \", \', \\, \n, \r, \t. Cualquier otro
escape se interpreta como el carácter literal que sigue.

4.4. Precedencia y asociatividad

1
2
3
4
5
6
7
%left  OR
%left AND
%left EQ NEQ
%left '<' '>' LE GE
%left '+' '-'
%left '*' '/' '%'
%right UMINUS '!'

Estas directivas resuelven la ambigüedad clásica de expr op expr op expr.

4.5. Resolución de ambigüedad: cond_expr vs. expr

Para evitar el conflicto entre el bloque que abre con { y un struct literal
que también empieza con IDENT '{' …, la condición de las sentencias if,
for y switch usa la regla cond_expr que excluye el struct literal
de primer nivel:

1
2
expr      : binary_expr | struct_literal ;
cond_expr : binary_expr ;

De este modo if Persona{Nombre:"Ana"} { … } no es ambiguo: la condición sólo
acepta operaciones, comparaciones e identificadores; los struct literals deben
ir precedidos por (...) o como parte de una expresión más interna.

4.6. Conflictos shift-reduce conocidos y resueltos

La gramática tiene varios conflictos shift-reduce que Jison resuelve a favor de
shift (lo deseado en cada caso):

  • IDENT seguido de {: prefiere construir un struct_literal antes que reducir
    el identificador a expresión simple.
  • IDENT seguido de otro IDENT: prefiere la regla de declaración estilo C
    (Tipo nombre = expr) antes que reducir a expresión.
  • RETURN seguido de un token de expresión: prefiere RETURN expr sobre
    RETURN desnudo.

Todos estos conflictos están documentados en el archivo goscript.jison.


5. Árbol de Sintaxis Abstracta (AST)

backend/src/ast/nodes.ts define los nodos como uniones discriminadas de
TypeScript: cada nodo tiene un campo kind literal que determina su forma, y
un campo loc: { line, column } con la posición del primer token que lo
originó.

5.1. Categorías de nodos

1
2
3
4
5
6
7
8
9
10
11
12
13
Program
├── declarations: TopLevelDecl[]

└── TopLevelDecl = FunctionDecl | StructDecl | VarDecl

Statement = VarDecl | AssignStmt | IncDecStmt | IfStmt | SwitchStmt
| ForStmt | ForRangeStmt | BreakStmt | ContinueStmt
| ReturnStmt | ExpressionStmt | BlockStmt

Expression = IntLiteral | FloatLiteral | StringLiteral | RuneLiteral
| BoolLiteral | NilLiteral | Identifier | GroupExpr
| BinaryExpr | UnaryExpr | MemberExpr | IndexExpr | CallExpr
| SliceLiteral | StructLiteral | AnonymousLiteral

5.2. Nodos compuestos relevantes

Nodo Campos clave
FunctionDecl name, params, returnType, body
StructDecl name, fields: FieldDecl[]
VarDecl name, declaredType, value, inferred
IfStmt condition, consequent, alternate (puede encadenarse en else if)
SwitchStmt expression, cases: CaseClause[], defaultBody
ForStmt init, condition, post, body (cubre las 3 variantes con ;)
ForRangeStmt indexName, valueName, iterable, body
SliceLiteral elementType (puede ser null si el tipo se hereda del padre), elements
StructLiteral typeName, fields: StructFieldInit[]
AnonymousLiteral fields: AnonymousField[] (cada uno con name? y value)

5.3. Composite literal anónimo

Para soportar la sintaxis estilo C Chip c = { serie: "X", … }, además de los
slices abreviados [][]int{ {1,2}, {3,4} }, el AST incluye dos nodos
flexibles que se materializan en tiempo de evaluación según el tipo destino:

  • AnonymousLiteral se usa como RHS de declaraciones tipo T x = { … }.
  • SliceLiteral con elementType: null se usa como elemento de un slice
    multidimensional cuyo tipo se hereda del slice padre.

Ambos casos los resuelve el intérprete en evalAnonymousLiteral y
evalSliceLiteral propagando el tipo desde el contexto.


6. Sistema de tipos y valores en tiempo de ejecución

6.1. TypeRef (backend/src/ast/types.ts)

Descripción estructural unificada de los tipos del lenguaje:

1
2
3
4
5
6
type TypeRef =
| { kind: 'primitive'; name: 'int'|'float64'|'string'|'bool'|'rune' }
| { kind: 'slice'; element: TypeRef }
| { kind: 'struct'; name: string }
| { kind: 'void' }
| { kind: 'nil' };

Funciones utilitarias:

  • typeToString(t) → representación legible ([]int, Persona, float64…).
  • sameType(a, b) → igualdad estructural.
  • isNumericType(t) → conveniencia para coerciones.

6.2. GValue (backend/src/runtime/values.ts)

Cada valor en tiempo de ejecución es una pareja { type, value }:

1
interface GValue { type: TypeRef; value: any }

Constructores: vInt, vFloat, vString, vBool, vRune, vNil,
vSlice(elemType, items), vStruct(name, fields).

Funciones clave:

  • defaultFor(type) — valor por defecto al declarar var x T sin valor:
    • int → 0, float64 → 0.0, string → "", bool → false, rune → 0,
    • slice → nil (value = null), struct → nil (value = null).
  • formatValue(v) — formateo para fmt.Println:
    • float64 con valor entero se imprime como 3.0 (no 3).
    • slice se imprime como [a b c] (separador espacio).
    • struct se imprime como Persona{nombre: Ana, edad: 25}.
    • rune se imprime como su carácter.

7. Operadores y reglas de coerción implícita

backend/src/runtime/operators.ts implementa las tablas exigidas por el
enunciado. Cada función toma dos GValue y devuelve uno; si la combinación
de tipos no es válida, lanza OpError que el intérprete convierte en error
semántico.

7.1. Suma +

izq \ der int float64 string bool rune
int int float64 string int int
float64 float64 float64 string float64 float64
string string string string string string
bool int float64 string bool (OR) int
rune int float64 string int int

Reglas resumidas:

  • Si alguno es string, el otro se convierte y se concatena.
  • Si alguno es float64, el resultado es float64.
  • bool + bool aplica OR lógico: true + false = true.
  • rune se promueve a int para sumar con enteros.

7.2. Resta - y multiplicación *

  • string - X no está permitido; produce error.
  • string * int (en cualquier orden) repite la cadena ("ab" * 3 = "ababab").
  • bool * bool aplica AND lógico.
  • Las demás combinaciones siguen la regla “el más amplio gana”
    (float64 > int > rune > bool).

7.3. División / y módulo %

  • / sólo entre numéricos (int, float64).
  • int / int da int (división truncada hacia cero).
  • Cualquier operando float64 produce float64.
  • % sólo entre int. Cualquier otra combinación → error.
  • División o módulo entre cero → error de ejecución.

7.4. Negación unaria -

Aplica a int, float64, rune, bool (este último convertido a 0/1).

7.5. Comparación ==, !=, <, <=, >, >=

  • Numéricos (int, float64, rune) se comparan promoviendo al más amplio.
  • string == string y bool == bool por valor.
  • nil es igual a nil (incluyendo slices y structs nil).
  • <, <=, >, >= aceptan numéricos y strings; no aceptan bool ni nil.

7.6. Lógicos &&, ||, !

Operan únicamente sobre bool; cualquier otro tipo lanza error semántico.
Implementan cortocircuito:

  • false && X no evalúa X.
  • true || X no evalúa X.

7.7. Coerción al asignar (coerceForAssign)

Interpreter.ts aplica una promoción mínima al asignar:

  • int o runefloat64: se convierte automáticamente.
  • nilslice o struct: se permite (slice/struct nil).
  • Mismo tipo: pasa sin cambios.
  • En cualquier otro caso desigual: error semántico.

8. Intérprete (recorrido del AST)

backend/src/interpreter/Interpreter.ts implementa un evaluador clásico de
recorrido en árbol con dos pasadas:

8.1. Pasada 1 — Registro global

Recorre program.declarations y registra:

  • Funciones (registerFunction): se valida que no choquen con otro símbolo
    global. Se anotan en la tabla de símbolos como Funcion.
  • Structs (registerStruct): igual, anotados como Struct.
  • Variables globales (execVarDecl con env = Global).

8.2. Pasada 2 — Ejecución de main

  • Si no existe main, registra error semántico y retorna.
  • Crea un Environment hijo del global llamado main y llama callFunction.

8.3. Señales de control de flujo

Para implementar break, continue y return sin coste de instrumentar todo
el árbol con guards manuales, el intérprete usa excepciones JavaScript como
señales:

  • BreakSignal — la captura el for o el switch envolvente.
  • ContinueSignal — la captura el for envolvente.
  • ReturnSignal — la captura callFunction y devuelve el valor.

Si una señal escapa al nivel global (por ejemplo un break fuera de un loop),
handleError la convierte en error semántico con la ubicación correspondiente.

8.4. Llamadas a función

evalCall decide la naturaleza de la llamada:

  1. Si el nombre cualificado (fmt.Println, len, …) corresponde a un
    built-in registrado, lo invoca con los argumentos ya evaluados.
  2. Si el callee es un Identifier que coincide con una función declarada por
    el usuario, llama callFunction(fn, args, loc).
  3. En otro caso, registra error semántico.

callFunction valida la cantidad de argumentos, crea un environment cuyo
padre es siempre el global (no captura el ámbito local del llamador,
imitando la semántica de Go sin closures), y declara los parámetros con la
coerción correspondiente.

8.5. Recursión

La recursión se soporta de forma natural porque las funciones se registran
antes de ejecutar main. El intérprete fue probado contra tribonacci(6),
mcdEuclides(48,18), potenciaRecursiva(2,10) y sumaNaturales(10) con
profundidades de hasta varios cientos de llamadas anidadas.

8.6. for-range sobre slices y strings

execForRangeStmt itera sobre el iterable declarando dos variables locales
por iteración:

  • indexName con tipo int y el índice secuencial.
  • valueName (opcional) con el valor actual:
    • Si el iterable es un []T, el valor tiene tipo T y es el elemento.
    • Si el iterable es un string, el valor tiene tipo rune y es el
      codepoint del carácter actual; los caracteres se separan por
      code points (compatibles con Unicode).

El identificador _ se acepta en posición de variable porque la gramática
lo trata como cualquier otro IDENT; sin embargo, no se realiza ningún
tratamiento especial: declarar dos veces _ en el mismo ámbito sí causa
error. En la práctica los ejemplos usan _ solo una vez por iteración.

8.7. Acceso y mutación de structs anidados

Los structs se representan internamente como Record<string, GValue> (un
objeto de JavaScript), por lo que el acceso area.equipo.chip.serie resuelve
referencias compartidas: mutar el struct más profundo se refleja en el padre
sin necesidad de copias explícitas.


9. Tabla de símbolos y manejo de ámbitos

9.1. Environment (backend/src/symbols/Environment.ts)

Cada bloque ({ … }), cuerpo de función, for o switch crea un
Environment hijo. La búsqueda de un símbolo (lookup) sube por la cadena
de padres hasta encontrarlo o llegar al global.

Operaciones soportadas:

  • declare(sym) — error si el nombre ya existe en el ámbito local
    (no impide ocultar uno del padre).
  • lookup(name) — recorrido ascendente.
  • lookupLocal(name) — sólo en el ámbito actual.
  • assign(name, value) — actualización in-place.

9.2. SymbolTable

Acumula todos los símbolos vistos durante la ejecución (incluidos los que
ya salieron de su ámbito) para producir el reporte final. Cada entrada
SymbolInfo registra: name, kind, type, value, scopeName, line,
column, mutable.

Las clases de símbolos son: Variable, Parametro, Funcion, Struct.


10. Manejo de errores

10.1. ErrorReporter

Singleton por ejecución. Cada error guarda:

1
{ id, kind: 'Léxico'|'Sintáctico'|'Semántico', description, line, column }

10.2. Origen de cada categoría

  • Léxico — el lexer encuentra un carácter fuera del alfabeto (regla
    LEXICAL_ERROR). Lo intercepta parser.lexer.parseError en parser.ts.
  • Sintáctico — el parser Jison falla. Lo intercepta parser.yy.parseError
    con la línea/columna y el token encontrado.
  • Semántico — registrado por el intérprete cuando un tipo no encaja, una
    variable no está declarada, una función recibe argumentos incorrectos, hay
    división entre cero, etc.

10.3. Resiliencia

El intérprete intenta continuar después de la mayoría de los errores
semánticos: por ejemplo, si una variable no existe, devuelve nil y reporta
el error en lugar de abortar. Esto permite ver varios errores en una sola
ejecución, lo cual mejora la experiencia en el IDE.


11. Funciones embebidas (built-ins)

Definidas en backend/src/builtins/index.ts. Cada built-in es una función
(args, ctx) => GValue registrada en un Map global.

Nombre Firma Notas
fmt.Println (...any) → void Imprime con espacio entre argumentos y \n final.
fmt.Print (...any) → void Igual a Println pero sin salto de línea.
strconv.Atoi (string) → int Devuelve 0 y reporta error si la conversión falla.
strconv.ParseFloat (string [, int]) → float64 El segundo argumento (precision) se acepta pero se ignora.
reflect.TypeOf (any) → string Devuelve la representación textual del tipo.
len (string | []T) → int nil slice devuelve 0.
append ([]T, ...T) → []T Crea un nuevo slice; no muta el original.
slices.Index ([]T, T) → int Devuelve -1 si no se encuentra. Comparación primitiva (===).
strings.Join ([]string, string) → string El separador debe ser string.

El contexto BuiltinContext provee:

  • print(text) y println(text) — escriben al buffer de salida.
  • reportError(msg) — registra un error semántico anclado a la línea/columna
    de la llamada.

12. Generación de reportes

12.1. AST → DOT (Graphviz) — reports/astDot.ts

Recorre el AST completo asignando un identificador entero a cada nodo y
emitiendo nodos y aristas con etiquetas y colores por categoría:

  • Verde para declaraciones globales.
  • Azul para sentencias (if, for, switch, return, …).
  • Naranja para operaciones binarias/unarias.
  • Morado para llamadas.

El frontend renderiza este DOT con @viz-js/viz para producir un SVG
interactivo descargable.

12.2. Tabla de símbolos → HTML — reports/symbolsHtml.ts

Genera un documento HTML autocontenido (estilos inline) con una tabla de
todos los símbolos. Se devuelve en la respuesta JSON y el IDE permite
descargarlo desde el panel Tabla de Símbolos.

12.3. Errores → HTML — reports/errorsHtml.ts

Mismo enfoque que la tabla de símbolos. Cada fila incluye id, tipo, descripción,
línea y columna, con codificación de color por categoría (rojo/amarillo/azul).


13. Frontend: IDE web

13.1. Stack y estructura

  • React 19 con hooks (useState, useEffect, useRef).
  • Vite 8 como bundler y servidor de desarrollo (puerto 5173).
  • Monaco Editor vía @monaco-editor/react con tema vs-dark y resaltado
    de Go (suficiente para GoScript).
  • Viz.js vía @viz-js/viz (instancia única cargada bajo demanda).
  • Sin librería de estado global; toda la lógica vive en App.tsx.

13.2. Modelo de pestaña

1
2
3
4
5
6
7
8
9
10
11
interface FileTab {
id: string; name: string; code: string; dirty: boolean;
output: string; // consola
errors: ApiError[]; // panel errores
symbols: ApiSymbol[]; // panel símbolos
astDot: string; astSvg: string; // AST: fuente DOT y SVG renderizado
symbolsHtml: string; // descarga directa
errorsHtml: string; // descarga directa
astRenderError: string | null;
isRunning: boolean;
}

Cada pestaña conserva sus propios resultados, así el usuario puede alternar
entre archivos sin perder la última ejecución de cada uno.

13.3. Persistencia (localStorage)

  • Clave: goscript-ide:workspace:v1.
  • Se guardan únicamente id, name, code, dirty (no resultados, son
    pesados y se recalculan ejecutando).
  • Debounce de 300 ms sobre cada cambio de tabs/activeId.
  • Al cerrar la ventana con tabs sucias, se dispara el aviso beforeunload.

13.4. Atajos de teclado

Combinación Acción
Ctrl/Cmd + S Guardar la pestaña activa (descarga .gst).
Ctrl/Cmd + N Nueva pestaña en blanco.
Ctrl/Cmd + W Cerrar la pestaña activa (con confirmación si está sucia).

13.5. Llamada al backend

handleRun envía POST {API_BASE}/api/run con { source }. La URL del API
puede sobrescribirse con la variable de entorno VITE_API_BASE al construir
el frontend; por defecto apunta a http://localhost:3001.

13.6. Renderizado del AST

El SVG del AST se calcula bajo demanda al abrir el panel AST, y queda
cacheado por pestaña. Si el DOT cambia (porque se reejecutó el código), se
limpia el SVG y se vuelve a renderizar.


14. Compilación y despliegue

14.1. Backend

1
2
3
4
5
6
7
cd backend
npm install
npm run build:grammar # genera src/grammar/generated/parser.js
npm run build # compila TS y copia el parser a dist/
npm start # ejecuta dist/server.js (puerto 3001)
# o bien:
npm run dev # tsx watch (recompilación al cambiar)

Variables de entorno opcionales:

  • PORT — puerto del API (por defecto 3001).

14.2. Frontend

1
2
3
4
5
cd frontend
npm install
npm run dev # vite dev server (puerto 5173)
npm run build # genera dist/ listo para producción
npm run preview # sirve dist/ localmente para verificarlo

Variables de entorno (Vite):

  • VITE_API_BASE — URL del API. Por defecto http://localhost:3001.

14.3. CLI auxiliar

backend/scripts/test-interpreter.js permite ejecutar archivos .gst desde
la terminal sin levantar el frontend, mostrando salida, errores y tabla de
símbolos. Útil para regresiones rápidas:

1
node backend/scripts/test-interpreter.js examples/evaluacion_funciones_prueba.gst

15. Limitaciones conocidas

Las siguientes funcionalidades no están implementadas porque quedan fuera
del alcance del enunciado:

  • Closures — las funciones no capturan variables del ámbito del llamador.
    Su entorno padre es siempre el global.
  • Funciones de orden superior — no se pueden pasar funciones como
    argumentos ni guardarlas en variables.
  • Múltiples valores de retorno — cada función devuelve a lo sumo un
    GValue (o ninguno).
  • Maps y canales — no se incluyen las estructuras map ni chan de Go.
  • Goroutines y select — el lenguaje es estrictamente secuencial.
  • Punteros y referencias explícitas — los slices y structs son objetos
    compartidos por referencia, pero no hay sintaxis *T ni &x.
  • Imports — los paquetes (fmt, strconv, etc.) se reconocen como
    prefijos sintácticos en las llamadas; no hay un sistema de módulos real.
  • Tipos con métodos — los structs no tienen métodos asociados, solo
    campos.

Estas limitaciones se documentan también en el Manual de Usuario.

avatar
Mynor Cifuentes
Mynor's personal blog
Follow Me
Announcement
Todo el código fuente compartido en este blog se encuentra bajo la licencia MIT. Puedes usar, modificar y distribuir el código para cualquier propósito, siempre y cuando incluyas la nota de copyright y la licencia original.