Walnut

Dan Lewis murpsoft at hotmail.com
Wed Jan 2 12:10:30 PST 2008


Alan Knowles Wrote:
> As you've opened the door - please regard the below as my personal 
> opinon, and take as such... ;)

Of course.  : )

If I may, please don't take this as a rejection of your help.  I'm simply explaining how I've come to where I am.  I'll probably implement at least some of these right away.

> 
> Value.d:
> You have made quite heavy use of op*** magic methods, Having done this 
> before a few times, it always bites me in the ass later on.. - as you 
> have to remember what magic is going to occur when you assign/create.

Yeah, the opAssign/opCall is only being used so I can go:
Value v = cast(Value) 4;

instead of:
Value v;
v.i = 4;
v.type = TYPE.NUMBER;

The only magic that ever happens there should be the automatic type property assignment.

Then there's the opCall(Value, Value, Value[] ...) which is to call Functions, and the opIndex, opIndexAssign, opIn_r which are to use Values as Objects.

The promotion of the Value struct to hold Function, Array and Object is a blatant diregard of the ECMAScript spec, however, it *is* semantically consistent, and consistent with the language itself.  It could be used to bring a significant structural advantage as we now have a single primitive to work with; and since the original form needed to disambiguate the type of a Value anyways.

> 
> It may be better to switch to more obvious/classic methods, - overloaded 
> constructors or an overloaded static method "construct()", / 
> to[typename], index(int id) etc.

I am actually starting to think that the Value.to[typename] format is cumbersome, as in all honesty, I'm not sure whether the output of a Value.toString() which is a Number object containing a value of 4 should be "4", "[object Number]", "4.0" (it's a double), or what.  I was then wondering how this should relate to the methods that we have; Object_prototype_toString, RegExp_prototype_source, etc.

So, there'll be a semantic change there somewhere to disambiguate, as I'm sure we both agree that ambiguity is bad.

> = This is going to make the future code alot easier to read, and 
> understand. (along with maintain, enable others to quickly work out what 
> is going on )
> 
> structure.d:
> I would be tempted to create a method to generate this type of code, 

It is very tedious to maintain that one.  I'll probably try to do something like that soon.

To expand, I had originally hoped to be able to use Associative Arrays, but they apparently contain a pointer to a complex hashing structure with even more pointers below.  I had hoped to simply sort the char[] pointing structures based on the strings alphabetically and do a binary search; which is probably faster for the small sets typically used for ECMAScript objects.

The structure.d file was an effort to create a static literal which wouldn't need any memcpy or anything of the sort; it would be loaded in via DMA straight from the file and be useable immediately.

> rather than trying to create a solution(the op*** stuff) for a problem 
> that would not have existed if you had gone down the road of using code 
> generators..
> Have a look at this to get an idea..
> http://www.akbkhome.com/svn/gtkDS/wrap/APILookupPhobos.txt
> 
> text.d:
> some of this could be autogenerated, and enum'd (might be clearer)
> eg...  TEXT.undefined

Definitely like the enum notation better.  : )

> 
> methods.d:
> again, using a code generator would give you benefit's of documentation 
> and using static D classes to encapsulate each Javascript class (along 
> with making smaller more manageable files..)

When I converted Walnut 1.x from DMDScript, I was mostly doing it to understand more of what Walter had written to learn how a good implementation looks.

I noticed that there was alot of redundancy in each of the files, and that my head was filling with all sorts of different constructs as I examined each file.  That's why I converted it to aspect oriented.  Now the code is so boringly simple that apart from value.d it reads like a list.

The problem with encapsulating JavaScript classes with D classes is that spec requires you to be able to expand JavaScript objects, so you eventually have to use an array notation inside that; as per DMDScript and Spidermonkey.  You end up duplicating several properties inside the array notation and class notation; and there's extensive code to look up the address of an ECMAscript property.  This is why even DMDScript property lookup is a few times slower than Lua or Io.

> 
> Not sure why your standard method call is using varargs (...) - unless I 
> misread the code..

The Value[] arguments was originally not a varargs, and you could pass it an array of Values just fine.  My interpretation of varargs is that it converts a set of Values to a Value[] at the caller by prepending the length?  So the varargs would simply mean you can now call the function passing:

(self, cc, arg1, arg2, arg3), as well as:

Value[] args = { arg1, arg2, arg3 };
(self, cc, args)

and that the call would look identical.

> interpreter.d
> (might be better to rename it tokenizer.d)

I'm (now) hoping to run the parser algorithms from the same file, and making sure it inlines the lexer.  I'm not sure if I want to generate tokens and then interpret them, or if I can use the finite state brought about by position in the lexer switch to somehow mean the same (preventing a double-switch).  The problem with that is that I can't seem to think beyond one token very well - the same one faced by the guys who invented separation of lexer, parser, interpreter.

> 
> Looks like the next big jobs would be:
> finish tokenizing (and do some test cases)
> creating the OPcodes.... (this part looks painful and time-consuming, 
> having seen dmdscript version. - parser / expression / statement etc.)

Yup.  I'm facing some analysis paralysis on this one, trying to come up with something cool (the wheel's already been invented, so why not do it round this time?)

> 
> Scope Management?
> Opcode runtime (~2800 lines of code in dmdscript)

Yeah, I was hoping to tie scope in with something during parsing of {}.  I've already got a Global object which is already being looked at for non-keywords in my [rather pathetic so far] lexer.  I think what I want is a bunch of Value's, which are of TYPE.OBJECT, or perhaps a new type just like it, which carry variables and stuff.

If I compile all functions down to (unoptimized) native code with the same call interface as the natives (my dream) then I could probably just use the stack to handle scope as per the natural way instead of faking it like most interpreters.

> 
> ---
> Unfortunately I detest forum's - old school (or stuborn), i prefer good 
> ole mailing lists (which I have for most D newsgroups, as I pull the 
> nntp feed into my mailbox)
> 
> I'm keeping an eye on Walnut, but I since most of my needs for 
> Javascript/DMDscript mean getting results very quickly from hacks to 
> DMDscript, I cant really justify to much real help to Walnut 
> unfortunately - but do keep working on it, as soon as the opcode 
> runtime, parser/opcode builder are done, I'd be pretty keen to retarget 
> all the binding code for DMDscript to be Walnut only.

Actually, Walnut 1.0 is branched from DMDScript, but I reformatted it, cleaned it up and the likes.  It almost has native ActiveX, moreso than JScript.  But there are major bugs that I don't understand.  Perhaps you'd be more prone to help there than Walnut 2.x.

Well, that was a HUGE ramble.
Regards,
Dan


More information about the Digitalmars-d-learn mailing list