<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://msmvps.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Angel "Java" Lopez : Smalltalk, C Sharp</title><link>http://msmvps.com/blogs/lopez/archive/tags/Smalltalk/C+Sharp/default.aspx</link><description>Tags: Smalltalk, C Sharp</description><dc:language>en</dc:language><generator>CommunityServer 2008.5 SP2 (Build: 40407.4157)</generator><item><title>AjTalk en C# (3) Environments</title><link>http://msmvps.com/blogs/lopez/archive/2012/12/27/ajtalk-en-c-3-environments.aspx</link><pubDate>Thu, 27 Dec 2012 17:10:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1821677</guid><dc:creator>lopez</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=1821677</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2012/12/27/ajtalk-en-c-3-environments.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2012/12/17/ajtalk-en-c-2-un-simple-servidor-web.aspx"&gt;Anterior Post&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Hace unas semanas, agregu&amp;eacute; el soporte de environments (ambiente, entorno) a mi proyecto de c&amp;oacute;digo abierto AjTalk, una m&amp;aacute;quina virtual Smalltalk escrita en C# (hay otras versiones, en Java y en JavaScript). &amp;iquest;Qu&amp;eacute; es un environment en mi jerga? Es un diccionario, donde puedo guardar artefactos por nombre, un directorio. Por ejemplo, para guardar clases por nombre. La variable global Smalltalk es un environment cl&amp;aacute;sico. Pero en un Smalltalk cl&amp;aacute;sico, todas las clases definidas van a parar a ese diccionario global, lo que puede dar lugar a colisi&amp;oacute;n de nombres. La forma normal de solucionar (p.ej. en Squeak y Pharo) es agregarle un prefijo (de dos letras) a cada clase de nuestra librer&amp;iacute;a. Pero yo quiero tener el soporte de tener otros environments, como pasa con los namespaces de .NET o los package de Java. Smalltalk cl&amp;aacute;sico tambi&amp;eacute;n tiene los llamados pool dictionary, pero hasta donde s&amp;eacute;, son para usar desde una clase y sus derivados. Yo quiero tener la noci&amp;oacute;n de paquete: todas estas clases se ven entre s&amp;iacute;, pero no est&amp;aacute;n en el environment del tope, en Smalltalk, sino en un environment dedicado a mi librer&amp;iacute;a. Agregu&amp;eacute; una implementaci&amp;oacute;n inicial, con estos tests:&lt;/p&gt;
&lt;p&gt;&lt;a title="https://github.com/ajlopez/AjTalk/blob/master/Src/AjTalk.Tests/AssertTests/EnvironmentTests.st" href="https://github.com/ajlopez/AjTalk/blob/master/Src/AjTalk.Tests/AssertTests/EnvironmentTests.st"&gt;https://github.com/ajlopez/AjTalk/blob/master/Src/AjTalk.Tests/AssertTests/EnvironmentTests.st&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Al comienzo, verifico que Smalltalk es un ambiente, un environment y es el actual:&lt;/p&gt;
&lt;pre style="background-color:black;max-width:600pt;color:white;font-size:10pt;"&gt;&amp;quot;Current environment is Smalltalk&amp;quot;
[Environment current == Smalltalk] assert.&lt;/pre&gt;
&lt;p&gt;Puedo crear nuevos entornos:&lt;/p&gt;
&lt;pre style="background-color:black;max-width:600pt;color:white;font-size:10pt;"&gt;env := Environment new: #MyEnvironment.&lt;/pre&gt;
&lt;p&gt;Autom&amp;aacute;ticamente, el nuevo entorno se registra/agrega al entorno actual, en este caso, a Smalltalk:&lt;/p&gt;
&lt;pre style="background-color:black;max-width:600pt;color:white;font-size:10pt;"&gt;&amp;quot;The new environment was defined as global at Smalltalk&amp;quot;

[(Smalltalk at: #MyEnvironment) isNil not] assert.
[(Smalltalk at: #MyEnvironment) == MyEnvironment] assert.
[(Smalltalk at: #MyEnvironment) == env] assert.

[MyEnvironment isNil not] assert.
[MyEnvironment == env] assert.&lt;/pre&gt;
&lt;p&gt;Cada nuevo entorno tiene autom&amp;aacute;ticamente una entrada Smalltalk que apunta al original global:&lt;/p&gt;
&lt;pre style="background-color:black;max-width:600pt;color:white;font-size:10pt;"&gt;&amp;quot;Dotted expression syntax sugar for MyEnvironment at: #Smalltalk&amp;quot;

[MyEnvironment.Smalltalk == Smalltalk] assert.&lt;/pre&gt;
&lt;p&gt;Podemos pasar a tener un nuevo entorno actual:&lt;/p&gt;
&lt;pre style="background-color:black;max-width:600pt;color:white;font-size:10pt;"&gt;env setCurrent.

&amp;quot;Current environment check&amp;quot;

[Environment current == env] assert.
[Environment current == Smalltalk.MyEnvironment] assert.&lt;/pre&gt;
&lt;p&gt;Y ahora, la caracter&amp;iacute;stica principal de lo que quer&amp;iacute;a implementar, de ahora en m&amp;aacute;s, las definiciones de clases (sin cambiar el c&amp;oacute;digo de su definici&amp;oacute;n) quedan registradas en el entorno actual:&lt;/p&gt;
&lt;pre style="background-color:black;max-width:600pt;color:white;font-size:10pt;"&gt;&amp;quot;Define a class at current env environment, no change to syntax&amp;quot;

Object subclass:#MyClass
    instanceVariableNames:&amp;#39;&amp;#39;
    classVariableNames:&amp;#39;&amp;#39;
    poolDictionaries:&amp;#39;&amp;#39;
    category:&amp;#39;&amp;#39;
.

[(env at: #MyClass) isNil not] assert.
[(Smalltalk at: #MyClass) isNil] assert.&lt;/pre&gt;
&lt;p&gt;Ortogonal a esto de environments, implement&amp;eacute; adem&amp;aacute;s m&amp;oacute;dulos (algo apareci&amp;oacute; en el post anterior): una forma de buscar y leer archivos file out, y ejecutarlos dentro de un nuevo entorno. Esto es similar al import de Python, y algo menos parecido, al require de Node.js/CommonJS. Bueno, pero eso es tema para otro post ;-)&lt;/p&gt;
&lt;p&gt;Nos leemos!&lt;/p&gt;
&lt;p&gt;Angel &amp;ldquo;Java&amp;rdquo; Lopez 
  &lt;br /&gt;&lt;a href="http://www.ajlopez.com"&gt;http://www.ajlopez.com&lt;/a&gt; 
  &lt;br /&gt;&lt;a href="http://twitter.com/ajlopez"&gt;http://twitter.com/ajlopez&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1821677" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/lopez/archive/tags/Smalltalk/default.aspx">Smalltalk</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/C+Sharp/default.aspx">C Sharp</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/AjTalk/default.aspx">AjTalk</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Proyectos+de+C_26002300_243_3B00_digo+Abierto/default.aspx">Proyectos de C&amp;#243;digo Abierto</category></item><item><title>AjTalk en C# (2): Un Simple Servidor Web</title><link>http://msmvps.com/blogs/lopez/archive/2012/12/17/ajtalk-en-c-2-un-simple-servidor-web.aspx</link><pubDate>Mon, 17 Dec 2012 16:45:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1821090</guid><dc:creator>lopez</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=1821090</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2012/12/17/ajtalk-en-c-2-un-simple-servidor-web.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2012/12/14/ajtalk_2D00_in_2D00_c_2D00_1_2D00_a_2D00_minimal_2D00_hello_2D00_world_2D00_image.aspx"&gt;Anterior Post&lt;/a&gt;&amp;nbsp;&lt;br /&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2012/12/27/ajtalk-en-c-3-environments.aspx"&gt;Siguiente Post&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Estoy trabajando completando mi m&amp;aacute;quina virtual Smalltalk, escrita en C#, el AjTalk, el repositorio en &lt;a href="https://github.com/ajlopez/AjTalk" title="https://github.com/ajlopez/AjTalk"&gt;https://github.com/ajlopez/AjTalk&lt;/a&gt; . Hace unas semanas, escrib&amp;iacute; un ejemplo de simple servidor web, basado en mi trabajo previo en &lt;a href="http://msmvps.com/blogs/lopez/archive/2012/12/08/pythonsharp_2D00_1_2D00_a_2D00_minimal_2D00_web_2D00_server.aspx"&gt;PythonSharp (1) Un servidor web m&amp;iacute;nimo&lt;/a&gt;. El c&amp;oacute;digo de este nuevo servidor en:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/ajlopez/AjTalk/blob/master/Src/AjTalk.Console/Programs/WebServer.st" title="https://github.com/ajlopez/AjTalk/blob/master/Src/AjTalk.Console/Programs/WebServer.st"&gt;https://github.com/ajlopez/AjTalk/blob/master/Src/AjTalk.Console/Programs/WebServer.st&lt;/a&gt;&lt;/p&gt;
&lt;pre style="background-color:black;color:white;font-size:12pt;overflow:scroll;"&gt;Object subclass: #WebServer
	instanceVariableNames: &amp;#39;root listener bytes&amp;#39;
	classVariableNames: &amp;#39;&amp;#39;
	poolDictionaries: &amp;#39;&amp;#39;
	category: &amp;#39;&amp;#39;
!

!WebServer class methods!

new
	^self basicNew initialize
! !

!WebServer methods!

initialize
	bytes := @System.Array !!CreateInstance: @System.Byte with: 1024 * 16.
	listener := @System.Net.HttpListener !!new.
	listener !!Prefixes !!Add: &amp;#39;http://*:8000/&amp;#39;.
	root := &amp;#39;c:/apache-tomcat-6.0.18/webapps/docs&amp;#39;.
	@System.Console !!WriteLine: &amp;#39;initialize&amp;#39;
!

process: context
	| filename input nbytes |
	filename := context !!Request !!Url !!AbsolutePath.
	
	@System.Console !!WriteLine: filename.
	
	(filename = &amp;#39;&amp;#39; or: [filename = &amp;#39;/&amp;#39;]) ifTrue: [filename := &amp;#39;index.html&amp;#39;].
	
	(filename !!StartsWith: &amp;#39;/&amp;#39;) ifTrue: [filename := filename !!Substring: 1].
	@System.Console !!WriteLine: filename.
	
	filename := @System.IO.Path !!Combine: root with: filename.

	@System.Console !!WriteLine: filename.	
	
	(@System.IO.File !!Exists: filename) 
	ifFalse: [ context !!Response !!Abort. ]
	ifTrue: [		
		input := @System.IO.FileStream !!new: filename with: @System.IO.FileMode !!Open.
		[[nbytes := input !!Read: bytes with: 0 with: bytes !!Length] value &amp;gt; 0] whileTrue: [
			context !!Response !!OutputStream !!Write: bytes with: 0 with: nbytes.
		].
		
		input !!Close.
		
		context !!Response !!OutputStream !!Close
	]
!

start
	listener !!Start.
	@System.Console !!WriteLine: &amp;#39;start&amp;#39;.
	[true] whileTrue: [
		| context |
		@System.Console !!WriteLine: &amp;#39;get context&amp;#39;.
		context := listener !!GetContext.
		@System.Console !!WriteLine: &amp;#39;new request&amp;#39;.
		self process: context.
	].
	@System.Console !!WriteLine: &amp;#39;end start&amp;#39;
! !

WebServer new start
!&lt;/pre&gt;
&lt;p&gt;Como el anterior, es una prueba de concepto, &amp;ldquo;quick and dirty&amp;rdquo;, para mostrar que puedo reutilizar las clases de .NET. Pueden lanzarlo desde el programa de consola de AjTalk (el resultado de compilar el proyecto AjTalk.Console):&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:Consolas;"&gt;ajtalk lib\Library.st Programs\WebServer.st&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;El resultado en &lt;a href="http://localhost:8000"&gt;http://localhost:8000&lt;/a&gt; (jeje, reusando unas p&amp;aacute;ginas est&amp;aacute;ticas que tengo en mi disco local):&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/ajtalkcs05.jpg" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;Luego escrib&amp;iacute; un ejemplo m&amp;aacute;s claro y modular en&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/ajlopez/AjTalk/blob/master/Src/AjTalk.Console/Programs/WebSiteTomcat.st" title="https://github.com/ajlopez/AjTalk/blob/master/Src/AjTalk.Console/Programs/WebSiteTomcat.st"&gt;https://github.com/ajlopez/AjTalk/blob/master/Src/AjTalk.Console/Programs/WebSiteTomcat.st&lt;/a&gt;&lt;/p&gt;
&lt;pre style="background-color:black;color:white;font-size:12pt;"&gt;Module import: #Web.

!

| server |

server := Web.Server new
	root: &amp;#39;c:/apache-tomcat-6.0.18/webapps/docs&amp;#39;;
	addPrefix: &amp;#39;http://*:8000/&amp;#39;;
	start
!&lt;/pre&gt;
&lt;p&gt;Pero ah&amp;iacute; estoy usando Module import:, algo que implement&amp;eacute; basado en lo que hice de PythonSharp import para cargar programas. Pero esa l&amp;oacute;gica ya es tema para otro post.&lt;/p&gt;
&lt;p&gt;Nos leemos!&lt;/p&gt;
&lt;p&gt;Angel &amp;ldquo;Java&amp;rdquo; Lopez 
  &lt;br /&gt;&lt;a href="http://www.ajlopez.com"&gt;http://www.ajlopez.com&lt;/a&gt;
  &lt;br /&gt;&lt;a href="http://twitter.com/ajlopez"&gt;http://twitter.com/ajlopez&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1821090" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/lopez/archive/tags/Smalltalk/default.aspx">Smalltalk</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/C+Sharp/default.aspx">C Sharp</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/AjTalk/default.aspx">AjTalk</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Proyectos+de+C_26002300_243_3B00_digo+Abierto/default.aspx">Proyectos de C&amp;#243;digo Abierto</category></item><item><title>AjTalk en C# (1): Una imagen mínima, con Hello, World</title><link>http://msmvps.com/blogs/lopez/archive/2012/12/14/ajtalk_2D00_in_2D00_c_2D00_1_2D00_a_2D00_minimal_2D00_hello_2D00_world_2D00_image.aspx</link><pubDate>Fri, 14 Dec 2012 12:50:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1820909</guid><dc:creator>lopez</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=1820909</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2012/12/14/ajtalk_2D00_in_2D00_c_2D00_1_2D00_a_2D00_minimal_2D00_hello_2D00_world_2D00_image.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2012/12/17/ajtalk-en-c-2-un-simple-servidor-web.aspx"&gt;Siguiente Post&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Si leen este blog (y tienen la paciencia de seguirme en Twitter ;-), ya saben que, luego de PyCon 2012 Argentina, he estado ocupado trabajando en mi m&amp;aacute;quina virtual Smalltalk AjTalk, escrita en C#:&lt;/p&gt;
&lt;p&gt;&lt;a title="https://github.com/ajlopez/AjTalk" href="https://github.com/ajlopez/AjTalk"&gt;https://github.com/ajlopez/AjTalk&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;He aqu&amp;iacute; un peque&amp;ntilde;o Hello, World:&lt;/p&gt;
&lt;pre style="background-color:black;width:1000px;color:white;font-size:12pt;"&gt;nil subclass:#Object
	instanceVariableNames:&amp;#39;&amp;#39;
	classVariableNames:&amp;#39;&amp;#39;
	poolDictionaries:&amp;#39;&amp;#39;
	category:&amp;#39;Kernel-Objects&amp;#39;
!

Object subclass:#Program
	instanceVariableNames:&amp;#39;&amp;#39;
	classVariableNames:&amp;#39;&amp;#39;
	poolDictionaries:&amp;#39;&amp;#39;
	category:&amp;#39;Kernel-Objects&amp;#39;
!

!Program class methods!

main @System.Console writeLine: &amp;#39;Hello, world&amp;#39;! !&lt;/pre&gt;
&lt;p&gt;En el repo:&lt;/p&gt;
&lt;p&gt;&lt;a title="https://github.com/ajlopez/AjTalk/blob/master/Src/AjTalk.Console/Programs/HelloWorld.st" href="https://github.com/ajlopez/AjTalk/blob/master/Src/AjTalk.Console/Programs/HelloWorld.st"&gt;https://github.com/ajlopez/AjTalk/blob/master/Src/AjTalk.Console/Programs/HelloWorld.st&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Podr&amp;iacute;a ser menor, pero necesito el Program main como punto de entrada de una imagen grabada en disco. El programa que genera la imagen es&lt;/p&gt;
&lt;pre style="background-color:black;width:1000px;color:white;font-size:12pt;"&gt;ajtalk Programas/HelloWorld.st &amp;ndash;s hello.im&lt;/pre&gt;
&lt;p&gt;y se lanza la imagen con&lt;/p&gt;
&lt;pre style="background-color:black;width:1000px;color:white;font-size:12pt;"&gt;ajtalk hello.im&lt;/pre&gt;
&lt;p&gt;De esta forma, AjTalk busca una variable global Program con un m&amp;eacute;todo main, y si existe, es invocado luego de la carga.&lt;/p&gt;
&lt;p&gt;La notaci&amp;oacute;n del nombre con @ para @System.Console es la forma que tiene AjTalk de referirse a tipos nativos de .NET.&lt;/p&gt;
&lt;p&gt;Noten que no cargo toda la librer&amp;iacute;a de clases, solamente las que necesito para ejecutar este Hello, world. AjTalk puede manejar varias m&amp;aacute;quinas en memoria, cada una de las cuales tiene sus propias clases y m&amp;eacute;todos. A&amp;uacute;n m&amp;aacute;s: le he agregado que una m&amp;aacute;quina virtual pueda operar sobre otra, y hasta &amp;ldquo;prestarle&amp;rdquo; sus m&amp;eacute;todos. De esta manera, puedo tener una m&amp;aacute;quina A con todas las clases de desarrollo, y manejar desde ah&amp;iacute; el contenido de la m&amp;aacute;quina B. Puedo entonces producir im&amp;aacute;genes m&amp;iacute;nimas. En vez de tener una sola y gran imagen en memoria, y hacer toda clase de contorsiones para reducirla, mis m&amp;aacute;quinas YA NACEN livianas por dise&amp;ntilde;o. Esto es un ejemplo de &amp;ldquo;pensar fuera de la caja&amp;rdquo;: por d&amp;eacute;cadas, los desarrolladores Smalltalk pensaron siempre en tener una sola imagen, y se metieron en el problema de COMO hacerla decrecer. Mi aproximaci&amp;oacute;n al problema es distinta: cada m&amp;aacute;quina va creciendo desde lo m&amp;iacute;nimo, y si es necesario usar algo (alg&amp;uacute;n m&amp;eacute;todo compile: por ejemplo), lo provee otra m&amp;aacute;quina, sin que tenga que crecer la primera.&lt;/p&gt;
&lt;p&gt;Tengo que escribir m&amp;aacute;s sobre lo que le agregu&amp;eacute; a esta versi&amp;oacute;n. Por ejemplo: objetos remotos (revisitado), m&amp;eacute;todos por objeto, procesos, sem&amp;aacute;foros, m&amp;uacute;ltiples threads, acceso a tipos nativos, grabar/leer im&amp;aacute;genes, un AST interno, visitors para recorrer ese &amp;aacute;rbol, generaci&amp;oacute;n de c&amp;oacute;digo para JavaScript, m&amp;oacute;dulos (a la import de Python o el require de Node.js), ambientes (como espacios de nombre, para evitar la colisi&amp;oacute;n de nombres), y bastante m&amp;aacute;s (como tener un Process que pueda ser suspendido y reanudado en cualquier momento, quiz&amp;aacute;s llegue a call con continuations).&lt;/p&gt;
&lt;p&gt;Nos leemos!&lt;/p&gt;
&lt;p&gt;Angel &amp;ldquo;Java&amp;rdquo; Lopez 
  &lt;br /&gt;&lt;a href="http://www.ajlopez.com"&gt;http://www.ajlopez.com&lt;/a&gt;
  &lt;br /&gt;&lt;a href="http://twitter.com/ajlopez"&gt;http://twitter.com/ajlopez&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1820909" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/lopez/archive/tags/Smalltalk/default.aspx">Smalltalk</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/C+Sharp/default.aspx">C Sharp</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/AjTalk/default.aspx">AjTalk</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Proyectos+de+C_26002300_243_3B00_digo+Abierto/default.aspx">Proyectos de C&amp;#243;digo Abierto</category></item><item><title>Trabajando de nuevo en on AjTalk: Smalltalk Virtual Machine, en C#</title><link>http://msmvps.com/blogs/lopez/archive/2012/11/30/trabajando-de-nuevo-en-on-ajtalk-smalltalk-virtual-machine-en-c.aspx</link><pubDate>Fri, 30 Nov 2012 16:19:05 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1820183</guid><dc:creator>lopez</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=1820183</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2012/11/30/trabajando-de-nuevo-en-on-ajtalk-smalltalk-virtual-machine-en-c.aspx#comments</comments><description>&lt;p&gt;Luego de trabajar en ejemplos distribuidos con Node.js (ver &lt;a href="http://ajlopez.wordpress.com/2012/09/22/simplega-1-genetic-algorithms-in-javascriptnode-js/"&gt;Genetic Algorithms&lt;/a&gt;), y en mi intérprete Python en .NET (&lt;a href="http://msmvps.com/blogs/lopez/archive/2012/11/17/mi-charla-en-pycon-argentina-2012-implementando-python.aspx"&gt;Post&lt;/a&gt;, &lt;a href="https://github.com/ajlopez/PythonSharp"&gt;GitHub repo&lt;/a&gt;), volví a trabajar en AjTalk, mi implementación de una VM Smalltalk. Tengo tres proyectos (&lt;a href="https://github.com/ajlopez/AjTalk"&gt;versión C#&lt;/a&gt;, &lt;a href="https://github.com/ajlopez/AjTalkJava"&gt;versión Java&lt;/a&gt;, &lt;a href="https://github.com/ajlopez/AjTalkJs"&gt;versión JavaScript&lt;/a&gt;), pero en estos días estroy trabajando en la versión C#.&lt;/p&gt;  &lt;p&gt;El fin de semana pasado, agregué un simple/ingenuo pero funcional grabado/lecturan de imágenes, y tengo un nuevo compilador de bytecodes: en vez de “parsear” el código y directamente generar “bytecodes”, ahora hay una implementación alternativa que construye un árbol AST, en memoria, y usando el patrón Visitorr, genera los “bytecodes” correspondientes. El año pasado había implementado el AST para con un Visitor ir recorriendo los nodos e ir generando código JavaScript, que se levanta con la versión AjTalk en JavaScript. El patrón Visitor podría usarse para generar distintas salidas, usando el mismo AST. Por ejemplo, tengo pensado como “prueba ácida”, armar un Visitor que genere Python (alternativas: que genere Ruby o C#, en este último caso exploraría el usar objetos dynamic).&lt;/p&gt;  &lt;p&gt;Desde hace tiempo, puedo crear más de una Machine: una imagen viva en memoria, cada una con su propio Object, Class, ClassDescriptor, etc. En vez de ser un Singleton, puedo crear y levantar desde imágenes más de una Machine. El código principal en:&lt;/p&gt;  &lt;p&gt;&lt;a title="https://github.com/ajlopez/AjTalk/blob/master/Src/AjTalk/Machine.cs" href="https://github.com/ajlopez/AjTalk/blob/master/Src/AjTalk/Machine.cs"&gt;https://github.com/ajlopez/AjTalk/blob/master/Src/AjTalk/Machine.cs&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Pude entonces generar una imagen mínima de un “Hello world” con menos de 300 bytes (! ;-), ver el código en:&lt;/p&gt;  &lt;p&gt;&lt;a title="https://github.com/ajlopez/AjTalk/blob/master/Src/AjTalk.Console/Programs/HelloWorld.st" href="https://github.com/ajlopez/AjTalk/blob/master/Src/AjTalk.Console/Programs/HelloWorld.st"&gt;https://github.com/ajlopez/AjTalk/blob/master/Src/AjTalk.Console/Programs/HelloWorld.st&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;También estube entrenando a los dos parsers para lean y ejecuten código de Pharo:&lt;/p&gt;  &lt;p&gt;&lt;a title="https://github.com/ajlopez/AjTalk/blob/master/Src/AjTalk.Tests/CodeFiles/PharoCoreKernelObjects.st" href="https://github.com/ajlopez/AjTalk/blob/master/Src/AjTalk.Tests/CodeFiles/PharoCoreKernelObjects.st"&gt;https://github.com/ajlopez/AjTalk/blob/master/Src/AjTalk.Tests/CodeFiles/PharoCoreKernelObjects.st&lt;/a&gt;     &lt;br /&gt;&lt;a title="https://github.com/ajlopez/AjTalk/blob/master/Src/AjTalk.Tests/CodeFiles/PharoKernelNumbers.st" href="https://github.com/ajlopez/AjTalk/blob/master/Src/AjTalk.Tests/CodeFiles/PharoKernelNumbers.st"&gt;https://github.com/ajlopez/AjTalk/blob/master/Src/AjTalk.Tests/CodeFiles/PharoKernelNumbers.st&lt;/a&gt;     &lt;br /&gt;&lt;a title="https://github.com/ajlopez/AjTalk/blob/master/Src/AjTalk.Tests/CodeFiles/PharoKernelClasses.st" href="https://github.com/ajlopez/AjTalk/blob/master/Src/AjTalk.Tests/CodeFiles/PharoKernelClasses.st"&gt;https://github.com/ajlopez/AjTalk/blob/master/Src/AjTalk.Tests/CodeFiles/PharoKernelClasses.st&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Y todo escrito usando TDD.&lt;/p&gt;  &lt;p&gt;Ahora que tengo varias máquinas en memoria, quiero implementar esta idea:&lt;/p&gt;  &lt;p&gt;- Cargar/Crear una Machine A (con sus clases, métodos, objetos) teniendo una librería completa de clases    &lt;br /&gt;- Cargar/Crear una Machine B, teniendo solamente algunas clases y objetos     &lt;br /&gt;- Hacer que la Machine A sea el “host” de la Machine B. Es decir, que se ocupe de darle lo que no tiene, ver el próximo punto.    &lt;br /&gt;- Reimplementar el proceso del mensaje #doesNotUnderstand en la Machine B para que, si el método correspondiente no es encontrado en esa máquina, la búsqueda del mismo continúe en la máquina “host”, la Machine A. De esta manera, podría usar todo el poder la Machine A, para operar sobre una Machine B más liviana, manteniendo la “liviandad” de ésta. La Machine A podría tener todas las herramientas de desarrollo, clases, objetos, métodos, mientras que la Machine B sigue teniendo un tamaño mínimo. Ideas similares están siendo exploradas por &lt;a href="http://twitter.com/morplenauta"&gt;@morplenauta&lt;/a&gt; (“committer” de Squeak, ver &lt;a href="http://ar.groups.yahoo.com/group/squeakRos/message/5651"&gt;la lista en español&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;(Actualización: hoy a la mañana, conseguí implentar lo de arriba, pero será tema de otro post).&lt;/p&gt;  &lt;p&gt;Otro proyecto: tener implementado un servidor web mínimo, que sirva archivo estáticos, aprovechando clases nativas de .NET, por ejemplo, lo de System.NET.&lt;/p&gt;  &lt;p&gt;Nos leemos!&lt;/p&gt;  &lt;p&gt;Angel “Java” Lopez    &lt;br /&gt;&lt;a href="http://www.ajlopez.com"&gt;http://www.ajlopez.com&lt;/a&gt;     &lt;br /&gt;&lt;a href="http://twitter.com/ajlopez"&gt;http://twitter.com/ajlopez&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1820183" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/lopez/archive/tags/Smalltalk/default.aspx">Smalltalk</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/C+Sharp/default.aspx">C Sharp</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/AjTalk/default.aspx">AjTalk</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Proyectos+de+C_26002300_243_3B00_digo+Abierto/default.aspx">Proyectos de C&amp;#243;digo Abierto</category></item><item><title>Popularidad de Lenguajes de Programación</title><link>http://msmvps.com/blogs/lopez/archive/2009/07/08/popularidad-de-lenguajes-de-programaci-243-n.aspx</link><pubDate>Wed, 08 Jul 2009 09:50:06 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1698705</guid><dc:creator>lopez</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=1698705</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2009/07/08/popularidad-de-lenguajes-de-programaci-243-n.aspx#comments</comments><description>&lt;p&gt;Me temo que &lt;a href="http://en.wordpress.com/tag/ajlisp/" target="_blank"&gt;AjLisp&lt;/a&gt; y &lt;a href="http://en.wordpress.com/tag/ajbasic" target="_blank"&gt;AjBasic&lt;/a&gt; lo usamos yo y nadie más… snif… :-). Pero hay lenguajes más populares que esos. Ya es clásica la lista de TIOBE Software:&lt;/p&gt;  &lt;p&gt;&lt;a title="http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html" href="http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html"&gt;http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.todocontenidos.com/images/articles/langpop01.png" alt="" /&gt; &lt;/p&gt;  &lt;p&gt;donde aparece Java como el lenguaje más popular, lo que no me asombra. Pero sí me llama la atención la popularidad de C y C++, que deben tener su gran uso en el ambiente Unix, Linux, y otros. Como cuarto, encuentro hoy, Julio de 2009, a PHP, que lo entiendo: la mayor parte del código de sitios dinámicos está en PHP, lejos quedaron los años del predominio del venerable Perl. Y recién en sexto y séptimo lugar, está Visual Basic (parece que agrupan el de .NET y el clásico), y C#. Vean que al final de la lista, aparecen lenguajes con mínimos porcentajes, pero aparecen: RPG, Pascal, Abap, Lisp/Scheme. Más abajo, en la misma página encontraran la lista de posición 21 a 50, donde aparecen COBOL, Objective-C, Fortran, Logo, Prolog, Ada (todavía anda por ahí? :-), Scala, Erlang…. y esta es la lista de 51 a 100:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;ABC, AD, Algol, Alpha, Applescript, Beta, Boo, C shell, cg, Clean, Cobra, cT, Curl, Dylan, Eiffel, Euphoria, Factor, Fan, Icon, IDL, Inform, Io, Lingo, MAD, Magic, Maple, Mathematica, MAX/MSP, MOO, MUMPS, Natural, Oberon, Occam, Oz, PL/I, Postscript, PowerBuilder, Progress, Q, R, Revolution, REXX, S-lang, SIGNAL, SPSS, SuperCollider, VBScript, Verilog, VHDL, XSLT&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Notable lista, recomendaría tantos lenguajes de esa lista, simplemente para aprender nuevas formas de programar (notable que aparezca todavía MUMPS, REXX, tendría que ver con más detalle a Io). Esta lista de popularidad se basa en el examen de búsquedas en Google, hace un tiempo pasaron a agregar MSN y Yahoo.&lt;/p&gt;  &lt;p&gt;Pero en estos días, encontré otra página:&lt;/p&gt;  &lt;p&gt;&lt;a title="http://langpop.com/" href="http://langpop.com/"&gt;http://langpop.com/&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.todocontenidos.com/images/articles/langpop02.png" alt="" /&gt; &lt;/p&gt;  &lt;p&gt;con información de ranking de popularidad, pero con agrupadas con distintas fuentes, como Yahoo Search, search en Google Code, Freshmeat, Craiglist, Amazon.&lt;/p&gt;  &lt;p&gt;En lo que veo hoy ahí, julio de 2009, según Yahoo Search C es más popular que Java. Pero para Craiglist, primero PHP, segundo SQL (!!!), en Amazon ganan C, C++ y C#, por encima de Java. Y así, noto dispersión de los resultados, dependiendo de la fuente.&lt;/p&gt;  &lt;p&gt;La popularidad de un lenguaje importa. No tanto para entender el lenguaje (muchos lenguajes “boutique” tienen interesantes conceptos, a estudiar con detalle), sino para tener una idea de qué tecnología ha sido adoptada por la comunidad, pero habría que ver más allá: por qué la eligieron, y en qué tipo de proyectos. Dudo que haya muchas aplicaciones desktop, en PHP.&lt;/p&gt;  &lt;p&gt;Resumen: gran cantidad de lenguajes, hay lenguajes viejos, desde COBOL y Smalltalk, y más “nuevos” como Boo, Ruby, Python. Y `cuatros grandes grupos: Java, C/C++, lenguajes .NET (VB.NET, C#), PHP, como claros grupos líderes.&lt;/p&gt;  &lt;p&gt;Pienso que, como desarrolladores de software, debemos tener contacto con esos cuatro grupos, y además, con alguno de los “otros”, para aprender otras ideas y formas de programar.&lt;/p&gt;  &lt;p&gt;No&amp;#160; me enojo si intentan ver &lt;a href="http://en.wordpress.com/tag/ajlisp" target="_blank"&gt;AjLisp&lt;/a&gt; o &lt;a href="http://en.wordpress.com/tag/ajbasic" target="_blank"&gt;AjBasic&lt;/a&gt;… :-)&lt;/p&gt;  &lt;p&gt;Nos leemos!&lt;/p&gt;  &lt;p&gt;Angel “Java” Lopez   &lt;br /&gt;&lt;a href="http://www.ajlopez.com"&gt;http://www.ajlopez.com&lt;/a&gt;    &lt;br /&gt;&lt;a href="http://twitter.com/ajlopez"&gt;http://twitter.com/ajlopez&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1698705" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/lopez/archive/tags/.NET/default.aspx">.NET</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Java/default.aspx">Java</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/PHP/default.aspx">PHP</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Smalltalk/default.aspx">Smalltalk</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Desarrollo+de+Software/default.aspx">Desarrollo de Software</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/C+Sharp/default.aspx">C Sharp</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/AjLisp/default.aspx">AjLisp</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/AjBasic/default.aspx">AjBasic</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Lenguajes+de+Programaci_26002300_243_3B00_n/default.aspx">Lenguajes de Programaci&amp;#243;n</category></item><item><title>AjTalk: un intérprete tipo Smalltalk</title><link>http://msmvps.com/blogs/lopez/archive/2008/07/15/ajtalk-un-int-233-rprete-tipo-smalltalk.aspx</link><pubDate>Tue, 15 Jul 2008 09:18:24 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1640872</guid><dc:creator>lopez</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=1640872</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2008/07/15/ajtalk-un-int-233-rprete-tipo-smalltalk.aspx#comments</comments><description>&lt;p&gt;Hace unas semanas, estuve trabajando en mi proyecto de código abierto AjTalk, un intérprete tipo Smalltalk, escrito en .NET (con C#, para facilitar la migración a Mono, si alguien lo necesita), y ahora, quiero presentar el estado actual de ese trabajo. Desde los tempranos ochenta del siglo pasado, me ha interesado Smalltalk y siempre vuelvo al tema, aunque sólo en mi tiempo libre, no como desarrollador profesional.&amp;nbsp;No es la primera vez que escribo un intérprete de este tipo (el primero que escribí en aquellos años era muy simple: en C, sin recolector de basura,&amp;nbsp;interface solo texto), pero ahora quiero implementar uno más, esta vez más completo,&amp;nbsp;apoyándome en&amp;nbsp;la librería de clases .NET.&lt;/p&gt; &lt;p&gt;La versión actual es mínima, pero va tomando forma. La idea es tener objetos dinámicos, como en Smalltalk, y, en algún momento, agregarle el soporte de prototipos. Los objetos y el intérprete accederían a todo el framework .NET y otras librerías. Tengo la experiencia previa de haber logrado eso en mi intérprete AjBasic, que uso en mi proyecto de generación de código&amp;nbsp;&lt;a href="http://www.ajlopez.com/ajgenesis" target="_blank"&gt;AjGenesis&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;La versión inicial de AjTalk está publicada en Google Code:&lt;/p&gt; &lt;p&gt;&lt;a title="http://code.google.com/p/ajtalk/" href="http://code.google.com/p/ajtalk/"&gt;http://code.google.com/p/ajtalk/&lt;/a&gt;&lt;/p&gt; &lt;p align="center"&gt;&lt;img src="http://www.ajlopez.com/images/articles/ajtalk01.png" alt="" /&gt; &lt;/p&gt; &lt;h3&gt;La solución&lt;/h3&gt; &lt;p&gt;&lt;img style="margin:0px 20px 20px 0px;" src="http://www.ajlopez.com/images/articles/ajtalk02.png" align="left" alt="" /&gt;&amp;nbsp;Estoy usando Visual Studio 2005 Professional. La solución contiene cuatro proyectos. &lt;/p&gt; &lt;p&gt;&lt;strong&gt;AjTalk&lt;/strong&gt; es el proyecto principal, una librería de clases conteniendo el núcleo del sistema. &lt;/p&gt; &lt;p&gt;&lt;strong&gt;AjTalk.Test01&lt;/strong&gt; y &lt;strong&gt;AjTalk.Test02&lt;/strong&gt; son aplicaciones de consola, para usar en pruebas manuales. &lt;/p&gt; &lt;p&gt;&lt;strong&gt;AjTalk.Tests&lt;/strong&gt; contiene los unit tests, escritos usando NUnit framework 2.2.8.&lt;/p&gt; &lt;p&gt;Mucho del sistema núcleo consiste en interfaces,&amp;nbsp;que definen&amp;nbsp;las conductas de base, y clases implementando esas interfaces.&lt;/p&gt; &lt;h3&gt;El objeto&lt;/h3&gt; &lt;p&gt;El proyecto contiene una interface para representar cualquier objeto:&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:5bc3d2fe-f4f7-427a-b6e9-b34b32ff74b2" style="padding-right:0px;display:inline;padding-left:0px;float:none;padding-bottom:0px;margin:0px;padding-top:0px;"&gt;&lt;pre style="background-color:White;white-space:-moz-pre-wrap;white-space:-pre-wrap;white-space:-o-pre-wrap;white-space:pre-wrap;word-wrap:break-word;"&gt;&lt;div&gt;&lt;span style="color:#0000FF;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; System;

&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;namespace&lt;/span&gt;&lt;span style="color:#000000;"&gt; AjTalk
{
    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;interface&lt;/span&gt;&lt;span style="color:#000000;"&gt; IObject
    {
        IClass Class { &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;get&lt;/span&gt;&lt;span style="color:#000000;"&gt;; }
        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;object&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;this&lt;/span&gt;&lt;span style="color:#000000;"&gt;[&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;int&lt;/span&gt;&lt;span style="color:#000000;"&gt; n] { &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;get&lt;/span&gt;&lt;span style="color:#000000;"&gt;; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;set&lt;/span&gt;&lt;span style="color:#000000;"&gt;;}
        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;object&lt;/span&gt;&lt;span style="color:#000000;"&gt; SendMessage(&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;string&lt;/span&gt;&lt;span style="color:#000000;"&gt; msgname, &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;object&lt;/span&gt;&lt;span style="color:#000000;"&gt; [] args);
    }
}
&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Podría hacer que un mensaje sea un objeto (del tipo Message), pero por ahora, el mensaje es sólo un nombre y un arreglo de argumentos.&lt;/p&gt;
&lt;p&gt;El índice this[int n] accesde a las variables de instancia. Cada valor en AjTalk puede apuntar a cualquier objeto .NET, no solamente a objetos que implementen IObject. De esta forma, puedo manejar int, long, String, DataSet, desde objetos IObject.&lt;/p&gt;
&lt;h3&gt;La clase&lt;/h3&gt;
&lt;p&gt;Estoy implementando una interface simple IClass, sin distinción entre clase, behavior, y otras clases, como sería en el Smalltalk clásico. Separaré esas clases en una futura versión, cuando llegue a ser necesario. Por ahora, estoy manejando sólo una interface:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:a3e6608b-9e4a-4b91-8364-c7fc6cac48f7" style="padding-right:0px;display:inline;padding-left:0px;float:none;padding-bottom:0px;margin:0px;padding-top:0px;"&gt;&lt;pre style="background-color:White;"&gt;&lt;div&gt;&lt;span style="color:#0000FF;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; System;
&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; System.Collections;
&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; System.Collections.Generic;

&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;namespace&lt;/span&gt;&lt;span style="color:#000000;"&gt; AjTalk
{
    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;interface&lt;/span&gt;&lt;span style="color:#000000;"&gt; IClass : IObject
    {
        IClass SuperClass { &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;get&lt;/span&gt;&lt;span style="color:#000000;"&gt;; }
        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;string&lt;/span&gt;&lt;span style="color:#000000;"&gt; Name { &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;get&lt;/span&gt;&lt;span style="color:#000000;"&gt;; }

        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;void&lt;/span&gt;&lt;span style="color:#000000;"&gt; DefineClassMethod(IMethod method);
        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;void&lt;/span&gt;&lt;span style="color:#000000;"&gt; DefineInstanceMethod(IMethod method);

        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;void&lt;/span&gt;&lt;span style="color:#000000;"&gt; DefineClassVariable(&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;string&lt;/span&gt;&lt;span style="color:#000000;"&gt; varname);
        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;void&lt;/span&gt;&lt;span style="color:#000000;"&gt; DefineInstanceVariable(&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;string&lt;/span&gt;&lt;span style="color:#000000;"&gt; varname);

        IObject NewObject();

        IMethod GetClassMethod(&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;string&lt;/span&gt;&lt;span style="color:#000000;"&gt; mthname);
        IMethod GetInstanceMethod(&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;string&lt;/span&gt;&lt;span style="color:#000000;"&gt; mthname);
        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;int&lt;/span&gt;&lt;span style="color:#000000;"&gt; GetClassVariableOffset(&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;string&lt;/span&gt;&lt;span style="color:#000000;"&gt; varname);
        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;int&lt;/span&gt;&lt;span style="color:#000000;"&gt; GetInstanceVariableOffset(&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;string&lt;/span&gt;&lt;span style="color:#000000;"&gt; varname);
    }
}

&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Hay un diccionaro para los métodos de clase y otro para los de instancia, y listas de variables de instancia y de clase. No soporta todavía variables indexadas. La interface IClass está implementada en la clase BaseClass.&lt;/p&gt;
&lt;h3&gt;El método&lt;/h3&gt;
&lt;p&gt;Hay una interface IMethod:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:1b757bb6-5b53-4539-b287-89d20a75c635" style="padding-right:0px;display:inline;padding-left:0px;float:none;padding-bottom:0px;margin:0px;padding-top:0px;"&gt;&lt;pre style="background-color:White;"&gt;&lt;div&gt;&lt;span style="color:#0000FF;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; System;

&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;namespace&lt;/span&gt;&lt;span style="color:#000000;"&gt; AjTalk
{
    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;interface&lt;/span&gt;&lt;span style="color:#000000;"&gt; IMethod
    {
        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;string&lt;/span&gt;&lt;span style="color:#000000;"&gt; Name { &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;get&lt;/span&gt;&lt;span style="color:#000000;"&gt;; }
        IClass Class { &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;get&lt;/span&gt;&lt;span style="color:#000000;"&gt;; }
        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;object&lt;/span&gt;&lt;span style="color:#000000;"&gt; Execute(IObject receiver, &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;object&lt;/span&gt;&lt;span style="color:#000000;"&gt; [] args);        
    }
}
&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;La clase concreta Método implementa esa interfaces. Su método Execute tiene:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:ab303446-f55f-4690-8722-afce0f37c90c" style="padding-right:0px;display:inline;padding-left:0px;float:none;padding-bottom:0px;margin:0px;padding-top:0px;"&gt;&lt;pre style="background-color:White;white-space:-moz-pre-wrap;white-space:-pre-wrap;white-space:-o-pre-wrap;white-space:pre-wrap;word-wrap:break-word;"&gt;&lt;div&gt;&lt;span style="color:#000000;"&gt;        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;object&lt;/span&gt;&lt;span style="color:#000000;"&gt; Execute(IObject receiver, &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;object&lt;/span&gt;&lt;span style="color:#000000;"&gt;[] args)
        {
            &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;return&lt;/span&gt;&lt;span style="color:#000000;"&gt; (&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;new&lt;/span&gt;&lt;span style="color:#000000;"&gt; ExecutionBlock(receiver,receiver,&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;this&lt;/span&gt;&lt;span style="color:#000000;"&gt;,args)).Execute();
        }
&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Los Execution blocks tienen variables locales y argumentos. El Execute de un bloque de ejecución toma instrucciones (bytecodes) desde métodos &amp;quot;compilados&amp;quot;, y los ejecuta. Aquí, me aparto de nuevo de Smalltalk original: acá el bloque de ejecución no es un objeto AjTalk. De esta forma, yo puedo ejecutar este intérprete sin necesidad de implementar gran cantidad de clases de base. Tengo que investigar las ventajas y problemas que esta decisión podría tener sobre el diseño e implementación de esta solución.&lt;/p&gt;
&lt;h3&gt;Los bytecodes&lt;/h3&gt;
&lt;p&gt;Tengo que meditar sobre usar un árbol de objetos (como en el patrón Interpreter) o bytecodes. En esta versión, uso bytecodes. Son las instrucciones básicas que mi &amp;quot;máquina virtul&amp;quot; entiende y ejecuta paso a paso.&lt;/p&gt;
&lt;p&gt;Esta es su enumeración:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:67906d46-f8c9-4bd2-ab64-5db089eea219" style="padding-right:0px;display:inline;padding-left:0px;float:none;padding-bottom:0px;margin:0px;padding-top:0px;"&gt;&lt;pre style="background-color:White;"&gt;&lt;div&gt;&lt;span style="color:#0000FF;"&gt;namespace&lt;/span&gt;&lt;span style="color:#000000;"&gt; AjTalk
{
    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;enum&lt;/span&gt;&lt;span style="color:#000000;"&gt; ByteCode : &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;byte&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    {
        Nop &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#000000;"&gt;0&lt;/span&gt;&lt;span style="color:#000000;"&gt;,
        GetVariable &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#000000;"&gt;1&lt;/span&gt;&lt;span style="color:#000000;"&gt;,
        SetVariable &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#000000;"&gt;2&lt;/span&gt;&lt;span style="color:#000000;"&gt;,
        GetArgument &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#000000;"&gt;3&lt;/span&gt;&lt;span style="color:#000000;"&gt;,
        SetArgument &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#000000;"&gt;4&lt;/span&gt;&lt;span style="color:#000000;"&gt;,
        GetConstant &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#000000;"&gt;5&lt;/span&gt;&lt;span style="color:#000000;"&gt;,
        GetLocal &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#000000;"&gt;6&lt;/span&gt;&lt;span style="color:#000000;"&gt;,
        SetLocal &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#000000;"&gt;7&lt;/span&gt;&lt;span style="color:#000000;"&gt;,
        GetClassVariable &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#000000;"&gt;8&lt;/span&gt;&lt;span style="color:#000000;"&gt;,
        SetClassVariable &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#000000;"&gt;9&lt;/span&gt;&lt;span style="color:#000000;"&gt;,

        GetSelf &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#000000;"&gt;20&lt;/span&gt;&lt;span style="color:#000000;"&gt;,
        GetClass &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#000000;"&gt;21&lt;/span&gt;&lt;span style="color:#000000;"&gt;,
        GetSuperClass &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#000000;"&gt;22&lt;/span&gt;&lt;span style="color:#000000;"&gt;,
        NewObject &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#000000;"&gt;23&lt;/span&gt;&lt;span style="color:#000000;"&gt;,
        Pop &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#000000;"&gt;24&lt;/span&gt;&lt;span style="color:#000000;"&gt;,
        ReturnSub &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#000000;"&gt;25&lt;/span&gt;&lt;span style="color:#000000;"&gt;,
        ReturnPop &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#000000;"&gt;26&lt;/span&gt;&lt;span style="color:#000000;"&gt;,

        Add &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#000000;"&gt;40&lt;/span&gt;&lt;span style="color:#000000;"&gt;,
        Substract &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#000000;"&gt;41&lt;/span&gt;&lt;span style="color:#000000;"&gt;,
        Multiply &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#000000;"&gt;42&lt;/span&gt;&lt;span style="color:#000000;"&gt;,
        Divide &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#000000;"&gt;43&lt;/span&gt;&lt;span style="color:#000000;"&gt;,

        Send &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#000000;"&gt;50&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    }
}
&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Los bytecodes contenidos en un método, son interpretados y ejecutados en un Execution Blog. Un fragmento de ese código:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:773713c4-82fc-4a18-b22d-9ce07963ecb1" style="padding-right:0px;display:inline;padding-left:0px;float:none;padding-bottom:0px;margin:0px;padding-top:0px;"&gt;&lt;pre style="background-color:White;"&gt;&lt;div&gt;&lt;span style="color:#000000;"&gt;    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;while&lt;/span&gt;&lt;span style="color:#000000;"&gt; (ip &lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; method.ByteCodes.Length) 
    {
        ByteCode bc &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; (ByteCode) method.ByteCodes&lt;img src="http://msmvps.com/emoticons/emotion-59.gif" alt="Paradise" /&gt;;
        Byte arg;

        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;switch&lt;/span&gt;&lt;span style="color:#000000;"&gt; (bc) 
        {
            &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;case&lt;/span&gt;&lt;span style="color:#000000;"&gt; ByteCode.ReturnSub:
                &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;return&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;null&lt;/span&gt;&lt;span style="color:#000000;"&gt;;
            &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;case&lt;/span&gt;&lt;span style="color:#000000;"&gt; ByteCode.ReturnPop:
                &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;return&lt;/span&gt;&lt;span style="color:#000000;"&gt; Top;
            &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;case&lt;/span&gt;&lt;span style="color:#000000;"&gt; ByteCode.GetConstant:
                ip&lt;/span&gt;&lt;span style="color:#000000;"&gt;++&lt;/span&gt;&lt;span style="color:#000000;"&gt;;
                arg &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; method.ByteCodes&lt;img src="http://msmvps.com/emoticons/emotion-59.gif" alt="Paradise" /&gt;;
                Push(method.GetConstant(arg));
                &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;break&lt;/span&gt;&lt;span style="color:#000000;"&gt;;
            &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;case&lt;/span&gt;&lt;span style="color:#000000;"&gt; ByteCode.GetArgument:
                ip&lt;/span&gt;&lt;span style="color:#000000;"&gt;++&lt;/span&gt;&lt;span style="color:#000000;"&gt;;
                arg &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; method.ByteCodes&lt;img src="http://msmvps.com/emoticons/emotion-59.gif" alt="Paradise" /&gt;;
                Push(arguments[arg]);
                &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;break&lt;/span&gt;&lt;span style="color:#000000;"&gt;;
....&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;h3&gt;Todo con Test&lt;/h3&gt;
&lt;p&gt;El código inicial había sido escrito en VB.NET. El año pasado lo comencé a pasar a C#. Este año cambié a modo &amp;quot;TDD&amp;quot;, tarde pero seguro, y agregué varios tests para el NUnit:&lt;/p&gt;
&lt;p align="center"&gt;&lt;img src="http://www.ajlopez.com/images/articles/ajtalktests.png" alt="" /&gt; &lt;/p&gt;
&lt;h3&gt;Bootstraping&lt;/h3&gt;
&lt;p&gt;Uso un archivo de texto, con un formato ad&amp;#39;hoc, para inyectar las definiciones iniciales de clases y objetos. Ahora, en el proyectos AjTest.Test02, hay un ejemplo de ese formato en el archivo Definitions.txt:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;font face="Consolas"&gt;class Point&lt;br /&gt;variables x y &lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Consolas"&gt;method&lt;br /&gt;x ^x. &lt;/font&gt;
&lt;p&gt;&lt;font face="Consolas"&gt;method&lt;br /&gt;y ^y. &lt;/font&gt;
&lt;p&gt;&lt;font face="Consolas"&gt;class Rectangle&lt;br /&gt;variables point1 point2&lt;br /&gt;class Square Rectangle &lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;h3&gt;Próximos pasos&lt;/h3&gt;
&lt;p&gt;Hay una pila de trabajo pendiente:&lt;/p&gt;
&lt;p&gt;- Completar la jerarquía de clases base (Behavior, Class, ....)&lt;/p&gt;
&lt;p&gt;- Implementar más bytecodes&lt;/p&gt;
&lt;p&gt;- Soporte de variables locales en métodos&lt;/p&gt;
&lt;p&gt;- Un archivo de text estándard&lt;/p&gt;
&lt;p&gt;- Acceso a objetos .NET nativos&lt;/p&gt;
&lt;p&gt;- Usar AjTalk desde aplicaciones .NET (no veo necesario entonces implementar una interface de ventanas en AjTalk, solamente consumirlo adecuadamente desde cualquier aplicación .NET)&lt;/p&gt;
&lt;p&gt;- Definir las clases y métodos para una implementación mínima&lt;/p&gt;
&lt;p&gt;- Serialización/deserialización de la imagen en memoria&lt;/p&gt;
&lt;p&gt;- Soporte de agregado de variables en una clase que ya tenga instancias creadas (puede ser un tema difícil)&lt;/p&gt;
&lt;p&gt;- Soporte de become: (el problema de todo intérprete)&lt;/p&gt;
&lt;p&gt;- Y mil más....&lt;/p&gt;
&lt;p&gt;Pero tengo confianza en la forma que va tomando el proyecto. Estoy aplicando &amp;quot;baby steps&amp;quot;, para mejorar el código de base y su funcionalidad. &lt;/p&gt;
&lt;p&gt;Este artículo en Anglish (Angel&amp;#39;s English):&lt;/p&gt;
&lt;p&gt;&lt;a href="http://ajlopez.wordpress.com/2008/07/14/ajtalk-a-smalltalk-like-interpreter/"&gt;AjTalk: a Smalltalk-like&amp;nbsp;interpreter &lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Nos leemos!&lt;/p&gt;
&lt;p&gt;Angel &amp;quot;Java&amp;quot; Lopez&lt;br /&gt;&lt;a href="http://www.ajlopez.com/en"&gt;http://www.ajlopez.com/en&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1640872" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/lopez/archive/tags/.NET/default.aspx">.NET</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Smalltalk/default.aspx">Smalltalk</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/C+Sharp/default.aspx">C Sharp</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/AjTalk/default.aspx">AjTalk</category></item></channel></rss>