¿Cómo imitar en S*BASIC el comando KEYIN de Beta BASIC?

Subforo oficial del Sinclair QL: realiza aquí las consultas relativas a tu QL.

Moderador: Sir Cilve Sinclair

Responder
Avatar de Usuario
programandala.net
Manic Miner
Mensajes: 210
Registrado: Mié Ago 04, 2010 9:20 pm
Ubicación: España
Contactar:

¿Cómo imitar en S*BASIC el comando KEYIN de Beta BASIC?

Mensaje por programandala.net » Mié Abr 06, 2011 3:25 pm

Los BASICs escritos por Andy Wright (Beta BASIC para ZX Spectrum; SAM BASIC y MasterBASIC para SAM Coupé) tienen un comando estupendo: KEYIN. Le das una cadena que contenga código en BASIC y lo ejecuta (y si lleva número de línea mete el código en el programa, lo que permite hacer programas que se modifiquen a sí mismos, aunque el KEYIN de las versiones de SAM Coupé tiene fallos y no es fiable para hacer esto). Una aplicación muy interesante de KEYIN es ejecutar código BASIC que tengamos en matrices, en ficheros o en DATAs. Esto es muy útil para programar árboles de decisión, por ejemplo.

Estoy intentando escribir KEYIN en S*BASIC para usarlo en un programa, pero no encuentro cómo.

Primer intento, con DO.

No funciona, porque DO detiene la ejecución del programa.

Código: Seleccionar todo

defproc keyin(sbasic_code$):rem first try
  rem Evaluate a string that contains S*BASIC code
  rem It doesn't work, because DO stops the program.
  loc file$,channel
  let file$="ram1_keyin_tmp"
  let channel=fop_over(file$)
  rem if channel<0:fatal_error "keyin: "&channel
  print #channel,sbasic_code$
  close #channel
  do file$
  delete file$
enddef


Segundo intento, con MERGE.

No funciona porque no se puede usar MERGE desde dentro de un procedimiento (o rutina), o mientras haya algún procedimiento o rutina que no esté cerrado (lo he descubierto en la práctica, porque el manual no dice nada de esto).

Código: Seleccionar todo

defproc keyin(sbasic_code$):rem second try
  rem Evaluate a string that contains S*BASIC code
  rem It doesn't work, because MERGE cannot be used inside a procedure or while any procedure is active.
  loc file$,merge_line,channel
  let file$="ram1_keyin_tmp"
  let merge_line=32767
  let channel=fop_over(file$)
  rem if channel<0:fatal_error "keyin: "&channel
  print #channel,merge_line&"defproc do_keyin:"&sbasic_code$&":enddef"
  close #channel
  merge file$
  do_keyin
  dline merge_line
  delete file$
enddef


Me estoy quedando sin ideas. He mirado en las extensiones que conozco pero no he encontrado ningún comando nuevo que haga esto.
Marcos Cruz (programandala.net)

afx
Sabreman
Mensajes: 396
Registrado: Dom Feb 24, 2008 10:56 pm

Re: ¿Cómo imitar en S*BASIC el comando KEYIN de Beta BASIC?

Mensaje por afx » Jue Abr 07, 2011 6:53 pm

Hummmm!!! ... programación "dinámica" con BASIC, eso sería genial.

En principio no se me ocurre nada limpio. Sólo la estrategia “bestia” típica de generar un segundo programa desde un programa SuperBasic, luego invocar a un compilador para compilar este programa generado, por último llamar ese nuevo programa generado e interactuar con él, tal vez aprovechado los pipes de QDOS. Structured SuperBASIC creo que tiene una utilidad Make que en el fondo traduce un programa SSB, lo convierte en SuperBASIC estándar y luego llama a Qliberator para compilarlo. Tal vez por ahí se pueda sacar alguna idea (no sé).

Avatar de Usuario
programandala.net
Manic Miner
Mensajes: 210
Registrado: Mié Ago 04, 2010 9:20 pm
Ubicación: España
Contactar:

Re: ¿Cómo imitar en S*BASIC el comando KEYIN de Beta BASIC?

Mensaje por programandala.net » Jue Abr 07, 2011 8:06 pm

afx escribió:Hummmm!!! ... programación "dinámica" con BASIC, eso sería genial..


Sí...! Bueno, mi objetivo concreto es más modesto: tener en DATAs los nombres de variables que sirven de identificadores de matrices, e ir asignándoles los valores según voy leyendo el contenido de las matrices, que también está en DATAs...

Es más fácil verlo con un ejemplo:

Código: Seleccionar todo

DIM x$(1,20)
DATA "charla","bla bla bla"
DATA "burla","tururú"


"bla bla bla" y "tururú" son los contenidos de x$(0) y x$(1), mientras "charla" y "burla" serían las variables que tras la lectura de las DATA quedarían con valores de 0 y 1 respectivamente, para poder usar en el programa:

Código: Seleccionar todo

print x$(charla):print x$(burla)


Así la legibilidad del programa aumenta, y no me tengo que preocupar de asignar los valores a las variables que sirven de índices (que además pueden cambiar al añadir o quitar elementos de la matriz.

La lectura de datos y asignación de valores sería así, con un hipotético comando KEYIN:

Código: Seleccionar todo

FOR n=0 to 1
  READ id$
  KEYIN "LET "&id$&"="&n
  READ x$(n)
END FOR n


Me han recordado que Turbo Toolkit tiene el comando TYPE_IN, que simula la entrada de código en una consola. Es lo que necesito, salvo que me sobra lo de que haya una consola y se tenga que ver cómo se "escribe" el comando! (Beta BASIC es más práctico: le pasa el código al intérprete directamente, sin escribir nada en la línea de comandos). Voy a intentarlo con TYPE_IN disimulando con algún truco lo de la consola y os contaré.
Marcos Cruz (programandala.net)

afx
Sabreman
Mensajes: 396
Registrado: Dom Feb 24, 2008 10:56 pm

Re: ¿Cómo imitar en S*BASIC el comando KEYIN de Beta BASIC?

Mensaje por afx » Vie Abr 15, 2011 9:45 am

Para lo que quieres, otra alternativa es buscar algún Toolkit que de soporte a enumerados (si lo que quieres es que los índices de las matrices lleven nombre con "semántica" en lugar de enteros). Desconozco si hay algúna extensión al SuperBASIC que "simule" tipos enumerados, pero me imagino que es exista algo.

Responder

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 7 invitados