QuickSilver 0.5 – Class Vars, Inst Vars, Self, Super, etc
February 8, 2011
http://www.silversmalltalk.com/index3.html
Above is QuickSilver 0.5 running in a Safari browser. The latest source code is here.
Code in the demo above is:
1 to: 100 do:[:i |
Vm println: i + ' hello world!'].
nil
There are several enhancements in version 0.5.
- self and super work properly
- instance variables and class variables
- proper metaclass hierarchy Object class superclass => Class
- true and false map to True and False classes repectively
There are the beginnings of a class hierarchy for widgets with default class variables:
TestWindow open
==>
opens a window
TestWindow initHeight: 75.
TestWindow open
==>
opens a smaller window
Tomorrow I will add cascades and improvements to block statement generation including support for non-local returns.
Also, I will change the main page of the site to run QuickSilver and then we can start building some community support tools.
February 9, 2011 at 4:41 am
Silver Smalltalk is Open source? GPL2?
February 9, 2011 at 8:09 am
It is open source.
MIT license.
February 9, 2011 at 6:53 am
One mini bug?
1 to: 100 do:[:i |
Vm println: i + ‘ hello world!’.
(each = 2) ifTrue:[^ each].
].
nil
Out must be
—
1 hello world!
2 hello world!
(^ out form method that include the block)
Please see fix on second example (solved with exception) of http://diegogomezdeck.blogspot.com/2006/07/st2js-traductor-de-smalltalk.html
February 9, 2011 at 8:08 am
Thank you Jose.
I have made a note of the bug and your blog page.
— Peter
February 9, 2011 at 9:14 am
Are you think on put your code on source repository (as google code)?
issue tracking, svn, downloadable versions, wiki page,…
GREAT WORK Peter!!
February 9, 2011 at 9:16 am
Yes, once it is functionally complete.
Perhaps next week.
February 9, 2011 at 5:08 pm
Peter, previous link is not my blog (i found googling: “smalltalk javascript”).
I like another (simple) solution witout exceptions…
Smalltalk:
1 to: 3 do:[:i |
Vm println: i + ‘ hello world!’.
(i=2) ifTrue:[^ i].
].
Javascript:
function() {
for(var i=1;i use null to check if inner blocks returns something
February 9, 2011 at 5:36 pm
Support for ‘non-local returns’ isn’t in version 0.5.
It will be in version 0.6 tomorrow along with support for cascades.
— Peter
February 9, 2011 at 5:55 pm
Peter let me fix my previous post…
Javascript:
1.- inner blocks (or anonymous js functions returns null at end).
2.- parent functions check if inner anonymous functions returns something not null to propagate.
note: if smalltalk inner blocks returns nill js compiler use Smalltalk.vars.nilObject => use null to check if inner blocks returns something
February 10, 2011 at 3:52 pm
Jose,
I pass a JavaScript object called _homeContext_. If any of the inner functions sets a return value in _homeContext_ it causes a return from the current block.
Version 0.6 is available.
Please see if you can find any cases where it fails.
Thanks,
— Peter
February 16, 2011 at 7:12 pm
I found a bug… performWithArgs lose _homeContext_
An example:
Using ifTrue: method works fine,
But using custom ‘if:then:’ fails (‘performWithArgs’ bug?),
Please note that:
· ‘performWithArgs’ calls to ‘if:then:’ with three when only need two (ignoring the third: ‘_homeContext_’).
· the check of ‘_homeContext_’ is inexistent in ‘performWithArgs’.
The code of ‘if:then:’ is,
February 17, 2011 at 9:22 am
Jose,
I haven’t looked into custom control structures yet.
They are certainly possible to implement.
This should be deferred to release 1.1.
— Peter
February 16, 2011 at 7:15 pm
I think that bug exist on every smalltalk method (called from ‘performWithArgs’) that use a Block as argument…
February 17, 2011 at 6:36 am
Another approach, to avoid additional parameters, are a special return class (ReturnValue) to return values and check the existence of block return…
Sorry for Java code, I extracted from an email that I sent to James Ladd (creator of Redline Smalltalk: Smalltalk on Java) => It’s simple translate it to Javascript code…
public class ReturnValue {
private Object value;
public ReturnValue(Object valueToReturn) {
this.value = valueToReturn;
}
public Object getValue() {
return value();
}
}
[/source]
And return this class on block returns
…
doReturn(value);
…
[/source]
Source code of doReturn:
public ReturnValue doReturn(Object value) {
if ( (value != null) && (value instanceof ReturnValue) ) {
return (ReturnValue) value;
}
return new ReturnValue(value);
}
[/source]
Then (all) internal Callers check the existence of return to propagate it
object result = call(method, arguments);
if (result != null && result instanceof ReturnValue) { doReturn(result) }
[/source]
And Parent (block creator) check the existence of return to return their real value
object result = call(method, arguments);
if (result != null && result instanceof ReturnValue) { return ((ReturnValue) result).value() }
[/source]
What do you think about this solution? It’s possible or see any inconvenient?
February 17, 2011 at 9:23 am
It may be better than the current solution.
Maybe in release 1.1.
— Peter
February 18, 2011 at 5:36 am
Peter, It’s not a bug on custom-control-structures, It’s a bug on any smalltalk method that received a Block as argument andis called from ‘performWithArgs’, you can duplicate this bug with this code:
(5 range) do:[:i | (i=3) ifTrue: [^99]]
when i is 3 breaks the loop an shows 99, but currently process all items on collection (0,1,2,3,4,5)
February 18, 2011 at 8:34 am
Jose,
I tried this:
10 range do:[:i |
i = 3 ifTrue:[^i].
Transcript println: i].
^nil
and it worked fine.
In your example, the range (0,1,2,3,4,5) will be returned at the end of loop execution regardless of where the loop exits. That is because the “do:” message returns the receiver when the loop finishes.
February 18, 2011 at 10:14 am
silversmalltalk code: please see Transcript before return…
Out:
1
2
3
4
5
Squeak code:
Out:
1
2
3
February 18, 2011 at 10:23 am
Please see:
Out: FINE (breaks on 3)
0
1
2
Out: WRONG (iterate 5 times)
0
1
2
3
4
5
February 18, 2011 at 10:58 am
Ok, that looks like a bug when the condition is the last statement.
I will add a “gen code” capability to the Vm class.
It will produce the JavaScript code without compiling or executing it.
Then we can look at the code to see what is happening.
You are doing good work Jose.
Thanks,
— Peter
February 18, 2011 at 12:06 pm
Hi Jose,
The problem is fixed. There was a condition check missing in the generated code for looping statements (to:do:, whileTrue:, etc).
Squeak:
#(0 1 2 3 4 5) do:[:i |
Transcript show: i;cr.
(i = 3) ifTrue:[^i].
]
shows 0,1,2,3 on the Transcript and returns 3
QuickSilver:
5 range do:[:i |
Transcript println: i.
(i = 3) ifTrue:[^i].
]
shows 0,1,2,3 on the Transcript and returns 3
same as Squeak.
QuickSilver 0.83 is now in the repository.
Thanks,
— Peter
February 18, 2011 at 12:10 pm
You’re as fast as ever… (is a pleasure)
February 17, 2011 at 6:39 am
Sorry, I fix my previous post:
Another approach, to avoid additional parameters, are a special return class (ReturnValue) to return values and check the existence of block return…
Sorry for Java code, I extracted from an email that I sent to James Ladd (creator of Redline Smalltalk: Smalltalk on Java) => It’s simple translate it to Javascript code…
And return this class on block returns
Source code of doReturn:
Then (all) internal Callers check the existence of return to propagate it
And Parent (block creator) check the existence of return to return their real value
What do you think about this solution? It’s possible or see any inconvenient?