Un compilador de ZX Spectrum BASIC

Todo sobre la creación, diseño y programación de nuevo software para
nuestro Spectrum

Moderador: Sir Cilve Sinclair

Avatar de Usuario
sromero
Nonamed
Mensajes: 1221
Registrado: Mar Abr 17, 2007 12:35 pm
Ubicación: Valencia
Contactar:

Re: Un compilador de ZX Spectrum BASIC

Mensaje por sromero » Jue Ene 31, 2008 7:43 am

Hernan escribió:
Boriel escribió: por emulador, el xspect, que admite .tzx (pasmo permite generar directamente .tzx).


El xspect tiene un millón de años, yo me decantaria por Fuse:

http://fuse-emulator.sourceforge.net/


Voto también por fuse, y más ahora que tienes un port para Windows (para otros usuarios que no tengan UNIX).
NoP / Compiler

Avatar de Usuario
Rafa
Jack The Nipper
Mensajes: 181
Registrado: Lun May 07, 2007 11:59 am

Re: Un compilador de ZX Spectrum BASIC

Mensaje por Rafa » Jue Ene 31, 2008 12:56 pm

Yo sigo pensando en coma flotante, porque un número puede valer 1 y 2 (enteros). Pero ¿ y si dentro del programa Basic una variable llega a tomar el valor 2.87? ¿Cómo introducimos esos decimales en asembler?
En el tema de nombrar variables, yo creo que tiene que haber una tabla definiendo esas variables por si después en otra línea se hace referencia a esa variable.
Por ejemplo:

10 let a=25
...

510 let h=a+19

Para compilarlo, habrá que buscar cuánto vale a en ese momento, es decir, dónde está almacenado el valor de a, y acoplarlo al programa. Para saber dónde está almacenado el valor de a, habrá que buscar primero dónde está la tabla de variables, y luego de entre todas las variables, cuál exactamente es a, y eso, corregidme si me equivoco, sólo se puede saber por su nombre. Yo creo que es lo que hace el intérprete Basic. Nosotros lo haríamos igual, pero más rápido.
RANDOMIZE USR 0

Avatar de Usuario
na_th_an
Nonamed
Mensajes: 1889
Registrado: Lun May 07, 2007 10:16 am
Ubicación: Andalucía

Re: Un compilador de ZX Spectrum BASIC

Mensaje por na_th_an » Jue Ene 31, 2008 1:02 pm

No es necesario. Eso se resuelve en tiempo de compilación. El código generado ya contiene direcciones de memoria en lugar de nombres de variable. No es necesario almacenarlas en ningún sitio en el binario. Claro que hará falta saberlo en tiempo de compilación, eso sí, pero eso lo hace el compilador y fuera del Speccy. No es necesario almacenar nada de memoria en el spectrum en tiempo de ejecución para almacenar nombres de variables (al menos eso fue lo que entendí que querías decir en tu anterior mensaje), pues ya no serán necesarios.

Sobre los formatos numéricos, para hacer juegos no suele ser necesario emplear punto flotante. Como bien ha dicho Boriel, el punto fijo es mucho más manejable, es fácil de implementar en ASM, y es increíblemente más rápido. Y la conversión a enteros suelen ser simples shifts. Si por ejemplo se define un formato de punto fijo de 4 bytes, 16bits de parte entera y 16 de parte decimal, por ejemplo, tenemos una precisión de 1/65536 lo cual está realmente bien. De todos modos, sea como sea, lo mejor es dejar que el programador elija entre entero o real. Es la mejor solución. Los BASICs basados en el dialecto de Microsoft permiten hacerlo desde finales de los 70. Es una de las grandes trabas del Sinclair BASIC, junto con el hecho de no disponer de operadores lógicos.

Cuando yo programo para compilar con HiSoft BASIC, defino todas las variables como INT, porque suelen ser juegos. Por lo general no es necesario el punto flotante para hacer juegos, sólo para aplicaciones científicas o estadísticas y cosas por el estilo.

Boriel
Sabreman
Mensajes: 351
Registrado: Lun May 28, 2007 9:55 am
Ubicación: Tenerife
Contactar:

La idea parece que puede funcionar

Mensaje por Boriel » Vie Feb 01, 2008 12:00 am

Bueno, ya entiende el comando BORDER :P

El programa de entrada fue:

Código: Seleccionar todo

10 BORDER 5
20 BORDER 2

Que genera el código:

Código: Seleccionar todo

; Program start
ORG 30000
ld a, 5
call 0x2297
ld a, 2
call 0x2297
ret

Que compilé con pasmo y ejecuté en xspect con RANDOMIZE USR 30000.
La prueba funcionó.

El programa ya "analiza" muchas otras instrucciones (la mayoría de ellas) pero NO las traduce aún. Por ejemplo, entiende BORDER <número constante entero>. Pero no compilará otras expresiones. La llamada anterior salta a la rutina BORDER de la ROM.

Lo de usar la ROM o no es un dilema, ya que en algunos casos ralentizará bastante la ejecución. Además, es probable que, como dijo Rafa, se obligue a crear las variables en RAM. Estoy buscando información sobre cómo usar la calculadora FP de la ROM (aunque ya he visto algo gracias al desensamblado del libro de Melbourne).

La otra opción es pasar bastante de la ROM. Entonces iría todo mucho más rápido, pero tendríamos algo como el BASIC HiSoft que ya ha comentado na_th_an (por cierto, he acabado en tu blog, gracias a Google). Y tampoco es eso. La idea es no renunciar mucho a la compatibilidad pero tampoco perder velocidad.

Algunas cosas a las que se renunciaría:
* READ, DATA y RESTORE, o al menos a DATA con variables y expresiones. Si no, tendremos que copiar gran parte de la ROM en RAM y "parchearla".
* Almacenar las variables como en BASIC (Con su nombre, etc). => No se podrá usar VAL$ (y puede que ni VAL para evaluar expresiones)
* Usar siempre punto flotante. El compilador puede saber, a veces, que una variable siempre será entera. En ese caso, optimizarla a entero de 8 ó 16 bits.
* Usar punto fijo, y sólo punto flotante para las funciones trigonométricas, etc. o no (ya se ha mencionado aquí)

Cosas que podría implementar y que creo que serían interesantes:
* Arrays multidimensionales de enteros y cadenas.
* Cadenas de caracteres de longitud variable (como en el BASIC, hasta lo que aguante la memoria)
* Usar el algoritmo de Bresenham y su equivalente para círculos, que sólo usan sumas, restas y desplazamientos de enteros.

Y así un largo etc. Estoy hecho un lío, la verdad.
De momento me gustaría saber donde encontrar información sobre la FP CALC de la ROM (no he encontrado nada, salvo el libro que no aclara mucho), cómo meter un valor en el stack de dicha calculadora, y como añadir una variable a memoria como lo haría BASIC. Sé que en algún número de Microhobby hablaban algo de eso (estoy buscando en MHoogle pero nada).

En fin, que estoy un poco en una encrucijada.

Avatar de Usuario
sromero
Nonamed
Mensajes: 1221
Registrado: Mar Abr 17, 2007 12:35 pm
Ubicación: Valencia
Contactar:

Re: La idea parece que puede funcionar

Mensaje por sromero » Vie Feb 01, 2008 7:49 am

Boriel escribió:Bueno, ya entiende el comando BORDER :P

El programa de entrada fue:

Código: Seleccionar todo

10 BORDER 5
20 BORDER 2

Que genera el código:

Código: Seleccionar todo

; Program start
ORG 30000
ld a, 5
call 0x2297
ld a, 2
call 0x2297
ret

Que compilé con pasmo y ejecuté en xspect con RANDOMIZE USR 30000.
La prueba funcionó.


Y digo yo ... ya que estás intentando generar un compilador que saque código rápido, ¿no sería mejor que cambiar el borde en ASM en lugar de simplemente llamar a la rutina de la ROM?

Código: Seleccionar todo

   ld a, BORDE_A_PONER
   ld c, 254
   out (c), a


Incluso si lo que te preocupa es que esto no actualiza la variable del sistema que guarda el borde para BASIC, puedes dejarlo así:

Código: Seleccionar todo

   ld a, BORDE_A_PONER
   ld c, 254
   out (c), a
   ld hl, 23624
   ld a, BORDE_A_PONER << 3
   ld (hl), a


(Está hecho de memoria, igual hay algo mal, pero se capta la idea).

O, tal vez, se podría dejar que BORDER llame a la rutina de la rom, y crear un nuevo comando BASIC para tu compilador llamado BORDER2 o BORDER_ASM que funcione en ASM.

Aunque yo voto por hacerlo todo lo mejor posible y luego implementar, por si acaso, rutinas BORDER_ROM.

saludos.
NoP / Compiler

Boriel
Sabreman
Mensajes: 351
Registrado: Lun May 28, 2007 9:55 am
Ubicación: Tenerife
Contactar:

Re: Un compilador de ZX Spectrum BASIC

Mensaje por Boriel » Vie Feb 01, 2008 9:22 am

Ahí está. Eso es lo que quería discutir:

Si hacemos todo como la ROM, no se ganará mucho. Es más, puede que incluso el programa ocupe mucha memoria, porque habrá que meter código extra (como has hecho tú), para actualizar variables de sistema, etc. Lo mismo con las variables, y los enteros.
De hecho, salvo la Calculadora FP de la ROM (por cierto, he visto rutinas más rápidas de Punto Flotante por ahí) todo lo demás, se podría hacer más rápido: El Plot, el Draw, el circle... El BEEP y el CLS si los aprovecharía.

Y el tema de que la interpretación de muchas instrucciones están mezclada con la ejecución lo complica todo aún mas. Algunas de esas instrucciones buscan variables en la memoria del BASIC (tendría entonces que declararlas y alterarlas cada vez que cambiara su valor). Multiplicaciones de enteros o punto-fijo se pueden hacer con el algoritmo de Booth, otra rutina interesante que he visto es la de impresión de un número en pantalla (ahorra mucho trabajo si es flotante). Pero si es entero, igual interesa más hacerla propia ya que también a la hora de hacer juegos, será más rápida. Etc.

Hacer instrucciones extendidas: BORDERX, DRAWX (Bresenham), CIRCLEX (Bresenham), por ejemplo, podrian extenderse.
Lo de no permitir cosas como DATA, se puede corregir, compilando cada valor de DATA como una función de cálculo. :roll: Pero no sé yo si eso es eficiente.
Y declarar tipos de variables byte, word (16 bits) y alguna otra en sentencias REM también aceleraría muchísimo, ya que se podría usar un registro para hacer un bucle por ejemplo.

Tal y como estoy diseñando la herramienta, el compilador puede, con el tiempo, ser más listo y hacer ciertas optimizaciones:

* Darse cuenta que una expresión matemática o variable siempre es entera (ej. solo usa +, -, *).
* Si una variable es entera, la expresión variable = variable + 1 se puede traducir como INC (variable) o una versión opimizada de la misma

Y un largo (largo) etcétera. Pero esto lo dejaría para para el final, cuando ya tengamos algo funcional.

En resumen: Tú opinas un poco como yo. Es mejor alejarnos un poco del BASIC del ZX (que, además, fue hecho pensando en ser interpretado), y pensar en programas Compilados para ganar eficiencia. Si alguien quiere sugerir otras cosas... (yo de momento, con generar el código de las evaluaciones matemáticas, ya voy a tomarme un rato largo en comentar novedades).

Avatar de Usuario
sromero
Nonamed
Mensajes: 1221
Registrado: Mar Abr 17, 2007 12:35 pm
Ubicación: Valencia
Contactar:

Re: Un compilador de ZX Spectrum BASIC

Mensaje por sromero » Vie Feb 01, 2008 9:33 am

Boriel escribió:Lo de no permitir cosas como DATA, se puede corregir, compilando cada valor de DATA como una función de cálculo. :roll: Pero no sé yo si eso es eficiente.


No sé, yo con los DATA haría lo siguiente.

En tiempo de compilación, si existen datas en el programa, te defines un área de memoria y un puntero tal que:

DATA_ZONE = [ zona de memoria ]
DATA_P = 0 (indice dentro de data_zone)

Luego, al compilar, vas guardando todos los datas que encuentras en DATA_ZONE.

La traducción a código de los data sería modificar el DATA_P para que apunte a la parte de DATA_ZONE donde están alojados esos datos, y READ se convierte en lecturas de DATA_ZONE[DATA_P] con incrementos de DATA_P...

No soy muy bueno con el BASIC del Spectrum, la verdad, pero igual esto es factible o al menos una variación de esto.

Igual estoy diciendo tonterías (ya os digo que se me da muy mal el BASIC del Spectrum), pero algo así se podría hacer.

De todas formas, me da la impresión de que te estás lanzando sin tener todavía una visión global del problema y un diseño de lo que quieres hacer, creo que así te va a tocar reescribir más de una vez lo que lleves hecho, cuando algo nuevo no te cuadre con el esquema que llevas hasta el momento (aunque menudos consejos doy precisamente yo X-D).
NoP / Compiler

Avatar de Usuario
na_th_an
Nonamed
Mensajes: 1889
Registrado: Lun May 07, 2007 10:16 am
Ubicación: Andalucía

Re: Un compilador de ZX Spectrum BASIC

Mensaje por na_th_an » Vie Feb 01, 2008 10:33 am

Yo es que opino que los DATA no son necesarios. Básicamente sirven para tener la información replicada en memoria (ya que por un lado tienes el fuente, y luego tienes que leerlos y meterlos en variables o donde sea). No sirven para nada. Prescindiría completamente de ellos.

VAL y VAL$ tampoco los veo yo muy utiles, dependiendo del contexto.

Tenemos que tener clara una cosa antes de empezar, y esto es la orientación que queremos darle al proyecto. BASIC es un lenguaje que está concebido para ser interpretado, por lo que tiene muchas cosas "únicas" que son, digamos, propias de un entorno interpretado, como puede ser el VAL, el VAL$, los DATAs, y cosas por el estilo.

Si yo me pusiera a hacer algo así (por la parte de Procesadores de Lenguajes podría hacerlo perfectamente, pero me falla la parte ASM que no tengo NPI y me falta que aprender mucho sobre optimización automática de código), optaría por una solución híbrida de esta manera:

1.- Los elementos propios de lenguaje interpretado los eliminaría por completo o los dejaría tirando de ROM cuando fuera posible. Por ejemplo, RESTORE/READ/DATA no tienen sentido en un programa compilado (ya que si quieres datos ya los tienes en memoria y los puedes leer con PEEK y poner con POKE). VAL y VAL$ son casi inútiles en juegos (a lo que yo orientaría un compilador así). De hecho creo que HiSoft basic ofrece un soporte muy limitado de VAL y no es compatible con VAL$ (no estoy seguro).
2.- Los bloques básicos de programación (instrucción selectiva, iterativa, etc...) los resolvería en ASM puro. No es complicado generar código para un bucle FOR o para un bloque IF.
3.- Las sentencias y funciones sencillas (PEEK, POKE, BORDER... ) las dividiría en dos grandes grupos: las más inmediatas que requieran poco código (por ejemplo un border) las pondría inline. Las otras (más complejas) las codificaría en una pequeña biblioteca de funciones que llamaría desde el código con CALL.

Fijáos además que si prescindimos de [1] tenemos código no dependiende de ROM, lo cual siempre es una buena cosa.

Pero si me preguntáis a mí, yo haría un rediseño del Sinclair BASIC eliminando números de linea y expandiendo con las cosas que le faltan.

Boriel
Sabreman
Mensajes: 351
Registrado: Lun May 28, 2007 9:55 am
Ubicación: Tenerife
Contactar:

Re: Un compilador de ZX Spectrum BASIC

Mensaje por Boriel » Vie Feb 01, 2008 10:46 am

En efecto. Había pensado algo así. Lo que pasa es que, a diferencia de otros BASIC, el del ZX permite expresiones con variables en las áreas de DATA:

Código: Seleccionar todo

10 LET a = 5
20 READ b
40 PRINT b
30 DATA a * a

Imprime 25. En este sentido el BASIC del ZX es mucho más potente que otros de la época. 8)

Había pensado hacerlo con una tabla de direcciones, como has mencionado, pero tendrían que ser punteros a funciones ASM que metan datos en al pila de la calculadora (FP-CALC o como se llame) de la ROM, cosa que todavía estoy tratando de averiguar (sacarlos ya sé).

Avatar de Usuario
Rafa
Jack The Nipper
Mensajes: 181
Registrado: Lun May 07, 2007 11:59 am

Re: Un compilador de ZX Spectrum BASIC

Mensaje por Rafa » Vie Feb 01, 2008 11:47 am

Yo creo que estáis enrevesando mucho el tema.
La idea del compilador surge para crear juegos, pero TAMBIÉN para traducir programas Basic ya hechos, y ganar velocidad.
Creo que deberíamos fijarnos en traducir un programa basic que corra en cualquier Spectrum, mirando primero la velocidad, y luego su longitud. También se pueden introducir sentencias nuevas, a través de REM, pero no funcionaría en un Spectrum normal (si no se modifica la ROM).

La idea del BORDER es buena actuando sobre el puerto 254. Es lo más rápido y correcto. Ahí va mi idea de POKE:

10 POKE 50000,31

CP POKE (CÓDIGO ASCII DE POKE)
JR Z,POKE1
...
POKE1 CALL ARGUM-2-INT ;SACAMOS DEL BASIC LOS DOS ARGUMENTOS ENTEROS SEPARADOS POR COMAS DEL POKE. DEVUELVE EN HL EL
; PRIMERO,
; EN DE EL SEGUNDO (PARA PODER USAR ESTA RUTINA CON TODAS LAS SENTENCIAS QUE NECESITEN DOS ARGUMENTOS)
LD A,E
LD (HL),A
ESTE CÓDIGO NO TARDA NI LA MITAD EN EJECUTARSE QUE UN POKE EN BASIC, Y ES MUCHO MÁS CORTO EN LONGITUD.
RANDOMIZE USR 0

Avatar de Usuario
Rafa
Jack The Nipper
Mensajes: 181
Registrado: Lun May 07, 2007 11:59 am

Re: Un compilador de ZX Spectrum BASIC

Mensaje por Rafa » Vie Feb 01, 2008 11:53 am

Los DATA son incluso más sencillos. Traducirlos por su valor en bytes y pokearlos en una zona libre. Después, con el READ, leerlos directamente de allí. Se puede usar un par de direcciones que marcarían los bytes de sentencias DATA más próximos para un READ. Y el RESTORE se refiere al número de línea donde aparecen esos DATA's. El RESTORE lo que haría sería modificar ese par de direcciones para que el READ lea en ellos.
RANDOMIZE USR 0

Avatar de Usuario
na_th_an
Nonamed
Mensajes: 1889
Registrado: Lun May 07, 2007 10:16 am
Ubicación: Andalucía

Re: Un compilador de ZX Spectrum BASIC

Mensaje por na_th_an » Vie Feb 01, 2008 11:55 am

Yo lo que quería expresar un poco con mi post es que a la hora de diseñar un compilador de BASIC deberíamos mirar hacia delante en vez de hacia atrás. Creo que orientar el desarrollo para que el producto nos sirva para compilar nuestros viejos programas no es tan interesante como diseñar un producto que nos sirva para desarrollar nuevos juegos. En ese caso, yo intentaría obtener un compilador potente que produjese un código rápido y portable, dejando la compatibilidad en un segundo plano.

Me reitero en que no veo util quebrarse la cabeza para implementar las construcciones RESTORE/READ/DATA y dotarlas de la misma funcionalidad que actualmente tienen, ya que admiten demasiada flexibilidad pero en un binario compilado dejan de ser utiles. Si queremos datos en memoria, como dije, lo mejor es tratarlos a mano con PEEK y POKE. Cuando yo programo juegos en BASIC para compilar con HiSoft es precísamente lo que hago. Además de ser más rápido, ocupa mucha menos memoria.

Imaginate que tenemos un compilador que admite DATA y los usamos en nuestro código. Tendríamos un binario con todos los datos almacenados en los DATA pero necesitaríamos tener bucles que leyesen esos DATA y los metiesen en nuestras arrays (por ejemplo), con lo que tendríamos partes de nuestro programa dedicadas a duplicar memoria. Gastamos memoria innecesaria tanto en los DATA como en ese código de inicialización, además de perder tiempo. Otra cosa distinta sería si los datos en DATA pudiesen ser manejados directamente, pero no es el caso.

Pero claro, esto es un problema de decidir qué orientación se le debe dar al proyecto. Yo lo tengo claro: yo crearía un compilador de un lenguaje Sinclair BASIC limpito (sin la parte puramente propia de su carácter original de lenguaje interpretado) y ampliado con los temas interesantes como pueden ser tipos de datos (por ejemplo definiendo INT8, INT8+, INT16, INT16+, FIXED y FLOAT), añadir operaciones a nivel de bit (esto es, NOT, AND y OR aritméticos y no sólamente lógicos. Actualmente 7 AND 2 devuelve "1" (AND lógico) en lugar de devolver "2" (AND aritmético), y esto supone una tremenda limitación), y definir cierta estructuración de código (bloques IF/ELSEIF/ELSE/ENDIF y procedimientos simples). Y permitiendo ASM en linea.

Boriel
Sabreman
Mensajes: 351
Registrado: Lun May 28, 2007 9:55 am
Ubicación: Tenerife
Contactar:

Re: Un compilador de ZX Spectrum BASIC

Mensaje por Boriel » Vie Feb 01, 2008 12:22 pm

na_th_an escribió:Pero claro, esto es un problema de decidir qué orientación se le debe dar al proyecto. Yo lo tengo claro: yo crearía un compilador de un lenguaje Sinclair BASIC limpito (sin la parte puramente propia de su carácter original de lenguaje interpretado) y ampliado con los temas interesantes como pueden ser tipos de datos (por ejemplo definiendo INT8, INT8+, INT16, INT16+, FIXED y FLOAT), añadir operaciones a nivel de bit (esto es, NOT, AND y OR aritméticos y no sólamente lógicos. Actualmente 7 AND 2 devuelve "1" (AND lógico) en lugar de devolver "2" (AND aritmético), y esto supone una tremenda limitación), y definir cierta estructuración de código (bloques IF/ELSEIF/ELSE/ENDIF y procedimientos simples). Y permitiendo ASM en linea.

Es precisamente, como había orientado el compilador al principio (los tipos, de hecho se llaman byte, word, fixed y float). Para los tipos enteros hay además versiones con y sin signo. Aparte del IF/ELSE, también había pensado en WHILE.

Otro proyecto era, directamente, quitar los números de línea y usar etiquetas, además de definición de funciones, etc. Pero eso se aleja mucho del BASIC del ZX, y a la gente que está muy metida en él no le va a gustar, me temo. Para mí, sería más cómodo de programar y es un lenguaje de más alto nivel que el BASIC del ZX (por ej. definir ámbitos de variables, etc, dentro de las funciones).

Avatar de Usuario
Rafa
Jack The Nipper
Mensajes: 181
Registrado: Lun May 07, 2007 11:59 am

Re: Un compilador de ZX Spectrum BASIC

Mensaje por Rafa » Vie Feb 01, 2008 12:42 pm

En definitiva estáis hablando de crear un lenguaje nuevo que nunca correrá en un Spectrum normal.
Estáis muy influenciados por C y los dichosos objetos...
¿Se necesita un while para programar en Basic (del Spectrum o no)?
¿Para qué necesitamos un AND aritmético? ¡¡ Aaarggghh, qué tremenda limitación !!
¿Qué importa si un número es float?
¿El uso de IF/ELSE os resuelve un problema?
¿Por qué no os gusta la programación lineal? (Y no digáis porque es obsoleta, es la respuesta típica.)
¿Por qué a mucha gente no les gusta el GOTO?

Si queréis crear un lenguaje NUEVO, hay otros foros. Yo me quedo con mi Speccy.
Y seguro que diréis que estoy anclado en el pasado...
Si yo visito este foro es porque me gusta mi Speccy TAL COMO ES.
RANDOMIZE USR 0

Avatar de Usuario
na_th_an
Nonamed
Mensajes: 1889
Registrado: Lun May 07, 2007 10:16 am
Ubicación: Andalucía

Re: Un compilador de ZX Spectrum BASIC

Mensaje por na_th_an » Vie Feb 01, 2008 1:07 pm

Rafa escribió:En definitiva estáis hablando de crear un lenguaje nuevo que nunca correrá en un Spectrum normal.

No, estamos hablando de un compilador de BASIC moderno, sin números de lineas, con tipos de datos y estructurado, como es BASIC desde 1984, aproximadamente, que pueda ser compilado a un bianrio que correrá en un Spectrum normal.

Estáis muy influenciados por C y los dichosos objetos...

C no tiene objetos :D De todos modos, creo que aquí nadie ha hablado de objetos.

¿Se necesita un while para programar en Basic (del Spectrum o no)?

No se necesita, pero se ve mucho más ordenado esto:

Código: Seleccionar todo

WHILE a > 1
   LET a = a + 1
WEND


que esto:

Código: Seleccionar todo

 10 LET a = a - 1: IF a > 1 THEN GO TO 10


Entre otras cosas porque el WHILE lo puedes mover a otra parte del código, sin tener que cambiar el GOTO ;)

¿Para qué necesitamos un AND aritmético? ¡¡ Aaarggghh, qué tremenda limitación !!

Para mil cosas. Por ejemplo, para ver si un número es par o impar, en Sinclair BASIC tienes que hacer:

Código: Seleccionar todo

IF INT(a/2) <> a/2 THEN PRINT "impar"

Con operadores a nivel de bit sólo necesitarías hacer:

Código: Seleccionar todo

IF a AAND 1 THEN PRINT "impar"

La diferencia es que actualmente necesitas hacer dos divisiones enteras y una conversión. Con operadores lógicos todo cambia por una simple operación a nivel de bits.

Con AND/OR aritméticos puedes usar variables enteras como contenedoras de muchas banderas. Para hacerlo actualmente tienes que hartarte de dividir y multiplicar. Para comprobar si el bit 3 de un dato leído de RAM con un PEEK está a 1 en el BASIC actual tienes que dividir, cuando con un "AAND 8" bastaría.

¿Qué importa si un número es float?

Importa y mucho. La aritmética flotante es muy lenta, y la mayoría de las veces no es necesaria. Si estás programando un juego, por ejemplo, no necesitas nunca tanta precisión. Si un lenguaje te deja elegir el tipo de datos de las variables, emplearás el que sea más adecuado. Si yo sé que mi variable va a tomar valores enteros de 0 a 255 ¿por qué exigir que guarde el valor en una variable que ocupa 5 bytes y que para operar con ella hay que hacer encaje de bolillos? Forzar al tipo real que maneja el Spectrum es una pérdida de tiempo y memoria en la mayoría de los casos.

¿El uso de IF/ELSE os resuelve un problema?

Sí, es más legible esto:

Código: Seleccionar todo

IF a = 0 THEN
   PRINT "Has ganado"
ELSE
   PRINT "Has perdido"
END IF

que esto:

Código: Seleccionar todo

10 IF a = 0 THEN PRINT "Has ganado": GOTO 30
20 PRINT "Has perdido"
30 REM


Y, además, ocurre lo mismo que con el WHILE. La opción con ELSE puede moverse a otro sitio si lo necesitamos sin tener que cambiar el GOTO.

¿Por qué no os gusta la programación lineal? (Y no digáis porque es obsoleta, es la respuesta típica.)

Porque dificulta reutilizar código, resulta poco legible, dificulta adaptar, o ampliar el código, impide la encapsulación, dificulta el parseo... ¿sigo? :D
¿Por qué a mucha gente no les gusta el GOTO?

Pregúntale a ellos. A mí me encanta :P

Si queréis crear un lenguaje NUEVO, hay otros foros. Yo me quedo con mi Speccy.
Y seguro que diréis que estoy anclado en el pasado...
Si yo visito este foro es porque me gusta mi Speccy TAL COMO ES.


No tiene nada que ver con el Speccy o el no Speccy. Se trata de hacer un compilador que genere código que se ejecute en un Speccy desde la comodidad de un PC. Y ya que se hace, debería estar bien diseñado. El diseño de Sinclair BASIC tiene cosas realmente buenas, pero otras realmente malas, aparte de lo que comentaba antes: está muy orientado a funcionar como intérprete, y nosotros estamos hablando de hacer un compilador :D

Yo también me quedo con mi Speccy. No veo qué tiene que ver el tocino con la velocidad :roll:

Responder

¿Quién está conectado?

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