No es una pregunta estúpida. Es una excelente pregunta.
Como ya se respondió, la respuesta corta es: "Otro idioma".
Bueno, eso lleva a algunas preguntas interesantes? ¿Qué pasa si es el primer idioma escrito para su pieza de hardware en particular? Un problema muy real para las personas que trabajan en dispositivos integrados. Como ya respondió "un idioma en otra computadora". De hecho, algunos dispositivos integrados nunca obtendrán un compilador, sus programas siempre se compilarán en una computadora diferente.
Pero puedes retrasarlo aún más. ¿Qué pasa con los primeros programas escritos?
Bueno, los primeros compiladores para "lenguajes de alto nivel" se habrían escrito en lo que se llama "lenguaje ensamblador". El lenguaje ensamblador es un lenguaje en el que cada instrucción en el idioma corresponde a una sola instrucción para la CPU. Su lenguaje de muy bajo nivel y extremadamente detallado y muy laborioso para escribir.
Pero incluso escribir lenguaje ensamblador requiere un programa llamado ensamblador para convertir el lenguaje ensamblador en "lenguaje máquina". Volvemos más lejos. Los primeros ensambladores se escribieron en "código de máquina". Un programa que consiste completamente en números binarios que son una correspondencia directa uno a uno con el lenguaje en bruto de la computadora misma.
Pero todavía no termina. Incluso un archivo con números apenas primas en que todavía necesita traducción. Aún necesita obtener esos números en bruto en un archivo en la computadora.
Bueno, lo creas o no, las primeras computadoras tenían una fila de interruptores en la parte delantera. Volteó los interruptores hasta que representaban un número binario, luego presionó otro interruptor y ese cargó ese número en la memoria de la computadora. Luego siguió moviendo el interruptor hasta que cargó un programa de computadora mínimo que podía leer programas de archivos de disco o tarjetas perforadas. Presionó otro interruptor e inició la ejecución del programa. Cuando fui a la universidad en los años 80, vi computadoras que tenían esa capacidad pero nunca se les dio la tarea de cargar un programa con los interruptores.
¡E incluso antes de eso, los programas de computadora tenían que estar conectados con tableros de enchufes !
La respuesta más común es
C
. La mayoría de los lenguajes se implementan en C o en un híbrido de C con devoluciones de llamada y un "lexer" como Flex y un generador de analizadores sintácticos como YACC . Estos son idiomas que se utilizan para un propósito: describir la sintaxis de otro idioma. A veces, cuando se trata de lenguajes compilados, primero se implementan en C. Luego, la primera versión del lenguaje se usa para crear una nueva versión, y así sucesivamente. (Como Haskell )fuente
Muchos idiomas tienen bootstrap, eso está escrito en sí mismos . En cuanto a por qué querrías hacer esto, a menudo es una buena idea comer tu propia comida para perros .
El artículo de wikipedia al que me refiero discute el tema del huevo y la gallina . Creo que lo encontrarás bastante interesante.
fuente
Prácticamente cualquier lenguaje, aunque usar uno adecuado para trabajar con gráficos y otras estructuras de datos complejas facilitará muchas cosas. Los compiladores de producción a menudo se escriben en C o C ++ por razones de rendimiento, pero los lenguajes como OCaml, SML, Prolog y Lisp son posiblemente mejores para la creación de prototipos del lenguaje.
También hay varios "pequeños idiomas" utilizados en el diseño de idiomas. Lex y yacc se utilizan para especificar la sintaxis y las gramáticas, por ejemplo, y se compilan en C. (Hay puertos para otros idiomas, como ocamllex / ocamlyacc y muchas otras herramientas similares).
Como caso especial, los nuevos dialectos de Lisp a menudo se basan en implementaciones de Lisp existentes, ya que pueden aprovechar la mayor parte de la misma infraestructura. Escribir un intérprete de Scheme se puede hacer en Scheme en una página de código, momento en el cual se pueden agregar fácilmente nuevas funciones.
Básicamente, los compiladores son solo programas que leen algo y lo traducen a otra cosa: convertir la fuente LaTeX a DVI, convertir el código C a ensamblado y luego a lenguaje de máquina, convertir una especificación gramatical a código C para un analizador, etc. Su diseñador especifica la estructura del formato de origen (análisis), qué significan esas estructuras, cómo simplificar los datos (optimización) y el tipo de salida a generar. Los intérpretes leen la fuente y la ejecutan directamente. (Los intérpretes suelen ser más simples de escribir, pero mucho más lentos).
fuente
En realidad, puedes escribir en casi cualquier idioma que desees. No hay nada que te impida escribir un compilador de C en Ruby. "Todo" que tiene que hacer es analizar el programa y emitir el código de máquina correspondiente. Si puede leer / escribir archivos, su lenguaje de programación probablemente será suficiente.
Si está comenzando desde cero en una nueva plataforma, puede hacer una compilación cruzada: escriba un compilador para su nueva plataforma, que se ejecute en Java o de forma nativa en x86. Desarrolle en su PC y luego transfiera el programa a su nueva plataforma de destino.
Los compiladores más básicos son probablemente Assembler y C.
fuente
"Escribir un nuevo lenguaje de programación" técnicamente no implica ningún código. Acaba de llegar a una especificación de cómo se ve su idioma y cómo funciona. Una vez que tenga una idea de cómo es su idioma, puede escribir traductores e intérpretes para que su idioma realmente "funcione".
Un traductor ingresa un programa en un idioma y emite un programa equivalente en otro idioma. Un intérprete ingresa un programa en algún idioma y lo ejecuta.
Por ejemplo, un compilador de C generalmente traduce el código fuente de C (el lenguaje de entrada) a un programa de lenguaje ensamblador (el lenguaje de salida). El ensamblador luego toma el programa de lenguaje ensamblador y produce lenguaje de máquina. Una vez que tenga su salida, no necesita los traductores para ejecutar su programa. Como ahora tiene un programa de lenguaje de máquina, la CPU actúa como intérprete.
Muchos idiomas se implementan de manera diferente. Por ejemplo,
javac
es un traductor que convierte el código fuente de Java a JVM bytecode. La JVM es un intérprete [1] que ejecuta el código de bytes de Java. Después de correrjavac
y obtener el código de bytes, ya no lo necesitajavac
. Sin embargo, cada vez que desee ejecutar su programa, necesitará la JVM.El hecho de que no sea necesario tener en cuenta a los traductores para ejecutar un programa es lo que hace posible "arrancar" su idioma sin tener que terminar ejecutándose "encima de" capas y capas de otros idiomas.
[1] La mayoría de las JVM traducen detrás de escena, pero en realidad no son traductores, ya que la interfaz de la JVM no es "idioma de entrada -> idioma de salida".
fuente
En general, puede usar casi cualquier idioma que desee. PHP fue escrito en C, por ejemplo. Si no tiene acceso a ningún compilador, tendrá que recurrir a escribir lenguaje ensamblador y compilarlo en código máquina a mano.
fuente
Muchos idiomas se escribieron primero en otro idioma disponible y luego se volvieron a implementar en sí mismos y se reiniciaron de esa manera (o simplemente mantuvieron la implementación en el idioma extranjero, como PHP y perl), pero algunos idiomas, como el primer ensamblador, se compilaron manualmente en código de máquina como El primer compilador C fue compilado a mano para ensamblar.
He estado interesado en el bootstrapping desde que lo leí. Para obtener más información, intenté hacerlo yo mismo escribiendo mi propio superconjunto de BF, que llamé EBF , en sí mismo. la primera versión de EBF tenía 3 primitivas adicionales y compilé a mano el primer binario. Encontré un ritmo de dos pasos al hacerlo. Implementé una función en el idioma actual en una versión y tuve una versión dulce donde reescribí el código para utilizar la función implementada. El lenguaje era lo suficientemente expresivo como para ser utilizado para hacer un intérprete de LISP .
Tengo la versión compilada a mano junto con la fuente en la primera etiqueta de lanzamiento y el código es bastante pequeño. La última versión es 12 veces más grande en tamaño y el código y permite un código más compacto, por lo que sería difícil compilar la versión actual a mano.
Edmund Grimley Evans hizo algo similar con su lenguaje HEX
Una de las cosas interesantes de hacerlo usted mismo es que comprende por qué algunas cosas son como son. Mi código fue producto si pequeños ajustes incrementales y parece que ha evolucionado en lugar de haber sido diseñado desde cero. Lo tengo en cuenta al leer el código hoy, que creo que parece un poco extraño.
fuente
Por lo general, con un lenguaje de programación de propósito general adecuado para el desarrollo de sistemas, por ejemplo, C, Haskell, ML, Lisp, etc., pero la lista de opciones es larga. Además, generalmente con algunos lenguajes específicos de dominio para la implementación del lenguaje, es decir, generadores de analizadores léxicos y analizadores, lenguajes intermedios como LLVM , etc. Y probablemente algunos scripts de shell, marcos de prueba y un sistema de configuración de compilación, por ejemplo, autoconf.
fuente
La mayoría de los compiladores eran wriiten C o un programa similar a ac, si no c, entonces ensamblar lang es el camino a seguir. Sin embargo, al escribir un nuevo lang desde cero y no tiene una macro lib o código fuente de un lenguaje prototipo, debe definir sus propias funciones ¿Ahora en qué idioma? Simplemente puede escribir un Formulario "de código fuente llamado psedocode en la máquina, se ve como una gramática bnf de la especificación lang estructurada orientada a objetos, como el algoritmo básico Fortran. Entonces, la imagen que escribe un código cruzado similar a cualquiera de estas sintaxis de lenguaje es código psedo
fuente
Incluso otras operaciones binarias o de ensamblaje deben traducirse en funciones, es decir, el trabajo de ensambladores / compiladores, luego en objetos, desde datos y funciones, si no tiene un archivo fuente para ver "cómo se debe representar la funcionalidad de estos objetos en su implementación del lenguaje, luego debe reconocer "ver" implementar, o definir sus propias funciones, procedimientos y estructuras de datos, lo que requiere mucho conocimiento, debe preguntarse qué es una función. Su mente se convierte en la simulación del lenguaje. Esto separa un programador maestro del resto.
fuente
Yo también tuve esta pregunta hace unos meses. Y leí algunos artículos y vi algunos videos que me ayudaron a comenzar a escribir mi propio idioma llamado soft. Todavía no está completo, pero aprendí muchas cosas de este viaje.
Lo básico que debe saber es cómo funciona el compilador cuando tiene que ejecutar un fragmento de código. El compilador tiene muchas fases como análisis léxico, analizador semántico, AST (Árbol de sintaxis abstracta), etc.
Lo que hice en mi nuevo idioma se puede encontrar aquí: http://www.singhajit.com/writing-a-new-programming-language/
Si está escribiendo un idioma por primera vez, todo lo mejor y tiene un largo camino por recorrer.
fuente
¿Qué son los lenguajes de programación en general?
los lenguajes de programación son solo una forma de hablar con las computadoras. en términos generales al principio porque las computadoras solo podían entender ceros y unos (debido al hecho de que las computadoras están hechas de transistores como interruptores que solo podían tomar dos estados, llamamos a estos dos estados 0 y 1) y trabajar con 0,1 fue difícil para nosotros, como humanos, los informáticos decidieron hacer un mapeo uno a uno de cada instrucción en binario (0,1) a una forma más legible para los humanos, que llamaron lenguaje ensamblador.
por ejemplo si tuviéramos una instrucción como:
11001101
en asamblea se llamaría:
CARGA_A 15
lo que significa que cargue el contenido del registro a en la ubicación de memoria 15. como dije, era solo una convención como elegir 0 y 1 para dos estados de los transistores o cualquier otra cosa en la computadora. De esta manera, tener un programa con 50 instrucciones, recordar el lenguaje ensamblador sería más fácil. entonces el usuario escribiría el código de ensamblaje y algún programa (ensamblador en este caso) traduciría los códigos a instrucciones binarias o lenguaje de máquina como lo llaman.
pero luego, con las computadoras mejorando cada día, había espacio para programas más complicados con más instrucciones, digamos 10000.
en este caso, un mapeo uno a uno como el ensamblaje no funcionaría, por lo que se crearon otros lenguajes de programación de alto nivel. Dijeron, por ejemplo, que si una relación con dispositivos de E / S para imprimir algo en la pantalla creada por el usuario toma alrededor de 80 instrucciones, déjenos hacer algo aquí y podríamos empaquetar todo este código en una biblioteca y llamarlo, por ejemplo, printf y también cree otro programa que podría traducir este printf aquí al código de ensamblaje relacionado y desde allí el ensamblaje haría el resto. entonces lo llaman compilador.
así que ahora cada usuario que quiera imprimir algo en la pantalla no tendría que escribir todas las instrucciones en binario o ensamblado, simplemente escribe printf ("algo") y todos los programas como el compilador y el ensamblador harían el resto. ahora más tarde, otros códigos más largos se empaquetarían de la misma manera para facilitar el trabajo de otras personas, ya que puede simplificar una línea de código de miles en un código en Python y empaquetarla para el uso de otras personas.
así que digamos que ha empaquetado muchos códigos diferentes en python y ha creado un módulo (libray, paquete o cualquier cosa que quiera llamarlo) y llama a ese módulo mgh (solo mi nombre). ahora digamos que hemos creado este mgh de alguna manera que cualquiera que diga:
podría conectarse fácilmente a un servidor remoto con la IP y el número de puerto especificado y enviar los datos después (o algo así). ahora la gente podría hacerlo todo con una sola línea, pero lo que sucede es que se están ejecutando muchos códigos que se han recuperado del archivo mgh. y empaquetar no ha sido para acelerar el proceso de ejecución sino más bien para facilitar el trabajo de otros programadores. así que aquí, si alguien quiere usar su código primero, debe importar el archivo y luego el intérprete de Python reconocerá todo el código y podrá interpretar el código.
ahora, si desea crear un lenguaje de programación y desea ejecutarlo, primero necesita una traducción, por ejemplo, supongamos que crea un programa que podría comprender la sintaxis y convertirla a c, en este caso después de que se haya traducido a c, el compilador de c se encargaría del resto, luego el ensamblador, el enlazador, .... aunque tendría que pagar el precio de ser más lento, ya que primero debe convertirse a c.
Ahora, otra cosa que podría hacer es crear un programa que pueda traducir todo el código al lenguaje ensamblador equivalente al igual que sucede con c, pero en este caso el programa podría hacerlo directamente y, a partir de ahí, el resto lo haría el enlazador. Sabemos que este programa se llama compilador.
así que de lo que estoy hablando es que, el único código que el sistema entiende es 0,1, por lo que de alguna manera deberías convertir tu sintaxis a eso, ahora en nuestros sistemas operativos muchos programas diferentes como ensamblador, enlazador y ... tienen creado para decirle que si pudiera convertir su código a ensamblado, ellos podrían encargarse del resto o, como dije, incluso podría usar otros compiladores de lenguajes de programación al convertir su código a ese idioma.
fuente