Índice de entradas del conversor
📘 Tabla de Contenidos
- 1) Definir el alcance y las variantes
- 2) Reunir / normalizar las gramáticas
- 3) Arquitectura general del transpilador
- 4) Reglas de mapeo
- 5) Estrategia para convertir GOTO/GOSUB
- 6) Conjunto mínimo de casos de prueba
- 7) Ejemplo de traducción básica
- 8) Ejemplo de posible mapeo de gráficos
- 9) Ejemplo de traducción (no trivial)
📝 Diseño de un Transpilador ZX Spectrum BASIC → QL SuperBASIC
Reinicio del proyecto (esta vez espero acabarlo…)
Retomo este proyecto con la intención firme de completarlo. Siempre he querido disponer de una herramienta capaz de traducir programas escritos en lenguaje ZX Basic del Spectrum al lenguaje SuperBASIC del Sinclair QL. Aunque ya he empezado varias veces, esta vez quiero estructurarlo bien para poder llegar al final. La idea es seguir una serie de pasos claros, desde la definición del alcance hasta la ejecución de pruebas reales.
Aunque ambos dialectos BASIC comparten muchos conceptos, tienen diferencias importantes que obligan a realizar transformaciones no triviales. En esta entrada describo la arquitectura general de un transpilador, enfocada a este caso concreto.
1) Definir el alcance y las variantes
✔ Lenguaje de origen
ZX BASIC (Spectrum):
- Líneas numeradas
GOTO,GOSUB,RETURNLET,RANDOMIZE,PLOT,INK,PAPER- Tokens gráficos
PEEK/POKE,USR- Comentarios con
REMo'
✔ Lenguaje destino
Sinclair QL SuperBASIC:
- No requiere números de línea
- Bloques
IF…END IF,REPeat,SELect ON - Procedimientos (
PROCedure) y funciones (DEFine FuNction) - I/O con canales (
OPEN,PRINT #ch) - Gráficos con
MODE,LINE,POINT
✔ Compatibilidad y variantes
- Compatibilidad con ZX80/81 BASIC
- Futuro soporte para Spectrum 128/+2/+3
- Ajuste de coordenadas y resoluciones
✔ Cobertura funcional
Cobertura mínima:
- Asignaciones y expresiones
- Estructuras:
IF,FOR,WHILE,GOTO,GOSUB - Arrays
PRINT/INPUT- Matemáticas básicas
Cobertura ampliada:
- Gráficos y sonido
MERGE,LOAD,SAVEON ERROR,ON x GOSUB- Manejo de cadenas
- Temporización / canales I/O
No soportado:
PEEK,POKE,USR
2) Reunir / normalizar las gramáticas
- Gramática del ZX BASIC: keywords, literales, tokens gráficos, comentarios.
- Gramática del SuperBASIC usada para validar la salida.
3) Arquitectura general del transpilador
- Lexer: obtener tokens.
- Parser + AST: nodos
Program,If,For,Print, etc. - Análisis semántico:
- Tabla de símbolos
- Detección de subrutinas
- Control de flujo (CFG)
- Tipos y arrays
- Transformación del AST:
- Eliminar números de línea
- Reescribir saltos
- GOSUB → PROCEDURE
- Normalización I/O
- Conversión gráfica
- Generación de código SuperBASIC
- Post‑procesado
4) Reglas de mapeo
4.1 Estructura y control de flujo
IF…THEN…ELSE→IF…END IFWHILE/WEND→REPeat+EXIT WHENGOTO→ intentar estructurarGOSUB→PROCedure
4.2 Variables y arrays
- BASIC Spectrum: base 1 → QL: base 0
- Cadenas
$ - Ajuste de rangos en
DIM
4.3 Entrada/Salida
PRINT/PRINT #chINPUT/INPUT #ch- Uso de
;y,
4.4 Funciones
SIN,COS,ABS,RNDRANDOMIZEVAL,STR$,LEFT$,RIGHT$
4.5 Gráficos y sonido
- Spectrum:
PLOT,DRAW,CIRCLE - QL:
POINT,LINE,CIRCLE - Atributos: sin equivalente
4.6 Memoria
PEEK,POKE,USR→ no portables
4.7 Errores
ON ERROR→ comportamiento diferente
5) Estrategia para convertir GOTO/GOSUB
- Construir un CFG
- Buscar patrones:
- If‑then →
IF…END IF - Saltos hacia atrás → loops
- Subrutinas →
PROCedure
- If‑then →
- Modo compatibilidad si no es seguro
6) Conjunto mínimo de casos de prueba
- Asignaciones
10 LET a=1: LET b=a+2: PRINT a+b - IF simple
10 IF a>10 THEN PRINT "OK" - IF con ELSE
10 IF a>10 THEN 20 PRINT "OK" 30 ELSE PRINT "NO" 40 END IF - FOR/NEXT
10 FOR i=1 TO 10: PRINT i: NEXT i - WHILE/WEND
10 LET i=0 20 WHILE i - GOSUB/RETURN
10 LET x=5: GOSUB 90: PRINT x: STOP 90 LET x=x*2: RETURN - Arrays y cadenas
10 DIM a(10): FOR i=1 TO 10: LET a(i)=i*i: NEXT i: PRINT a(5) 20 LET s$="HELLO": PRINT LEN s$, RIGHT$(s$,2) - Gráficos
10 PLOT 10,10: DRAW 20,0: CIRCLE 30,30,10
7) Ejemplo de traducción básica
Entrada ZX Spectrum BASIC:
10 REM Calculo de suma
20 LET s=0
30 FOR i=1 TO 10
40 LET s=s+i
50 NEXT i
60 IF s>50 THEN PRINT "MAYOR"; ELSE PRINT "MENOR O IGUAL";
65 PRINT " DE 50"
70 GOSUB 90
80 PRINT "FIN": STOP
90 PRINT "TOTAL=";s: RETURN
Salida QL SuperBASIC:
REM Calculo de suma
s = 0
FOR i = 1 TO 10
s = s + i
END FOR
IF s > 50 THEN
PRINT "MAYOR";
ELSE
PRINT "MENOR O IGUAL";
END IF
PRINT " DE 50"
PROC_show_total(s)
PRINT "FIN"
STOP
PROCedure PROC_show_total(total)
PRINT "TOTAL="; total
END PROCedure
8) Ejemplo de posible mapeo de gráficos
Spectrum:
10 INK 2: PAPER 0: CLS
20 PLOT 10,10: DRAW 50,0
30 CIRCLE 40,40,10
QL:
INK 2 : PAPER 0 : CLS
POINT 10,10
LINE 10,10 TO 60,10
CIRCLE 40,40,10
9) Ejemplo de traducción (no trivial)
10 REM Serie, demo graficos y subrutina
20 LET s=0: LET x=64: LET y=64
30 FOR i=1 TO 5
40 LET s=s+i
50 NEXT i
60 IF s>10 THEN PRINT "MAYOR";: PRINT " "; s ELSE PRINT "NO";: PRINT " "; s
70 PLOT 10,10: DRAW 20,0: DRAW 0,20: DRAW -20,0: DRAW 0,-20
80 GOSUB 200
90 DATA 3,5,8
100 READ a,b,c
110 PRINT "DATA:"; a; ","; b; ","; c
120 STOP
200 REM duplica s
210 LET s=s*2
220 RETURN
Salida QL:
100 REMark Calculo de suma
110 REMark Serie, demo graficos y subrutina
120 CLS
130 s=0
140 x=64
150 y = 64
160 FOR i = 1 TO 5
170 s = s + i
180 END FOR i
190 IF s > 10 THEN
200 PRINT "MAYOR";
210 PRINT " "; s
220 ELSE
230 PRINT "NO";
240 PRINT " "; s
250 END IF
270 REMark Gráficos: PLOT y DRAW relativo
280 INK 7 : PAPER 0
290 __gx = 10 : __gy = 10
300 POINT __gx, __gy
310 LINE __gx, __gy TO __gx + 20, __gy
320 LINE __gx, __gy TO __gx, __gy + 20
330 LINE __gx, __gy TO __gx - 20, __gy
340 LINE __gx, __gy TO __gx, __gy - 20
350 PROC_duplica_s(s)
370 _DATA_INIT
390 FOR i=1 TO 3
400 PRINT _READ
410 END FOR i
450 DEFine PROCedure PROC_duplica_s(by_s)
460 s = s * 2
470 END DEFine
490 DEFine PROCedure _DATA_INIT
500 Data_Init = 0
510 END DEFine
530 DEFine FuNction _READ
540 IF Data_Init <> 1 THEN _DATA
560 __DATA(0) = __DATA(0) + 1
570 RETurn __DATA(__DATA(0))
580 END DEFine _READ
600 DEFine PROCedure _DATA
620 Data_Init = 1
630 DIM __DATA(3)
640 __DATA(0) = 0
650 __DATA(1) = 3
660 __DATA(2) = 5
670 __DATA(3) = 8
680 END DEFine
No hay comentarios:
Publicar un comentario