Making a programming language Part 7b - using objects
Table of contents, Whole project on github
Something like EPIC FAIL occured to me and I published a post containing only half the content I intended to write. So I’m doing a part b.
My intended usage of objects is something along the lines of
objectName.someProperty
objectName.someFunction()
someFunction().someProperty
someObject.someProperty.someFunction().someProperty.someFunction
Explanation
- getting a value from an object
- invoking a function contained in an object
- getting a value from returned object of the invoked function
- a bit contrived example. Invoking a function contained inside a property(object) of an object and then getting a function value from a property of the returned value from the first function. That’s a mouthful, just read the damn code instead
Dot access
So everything bases on those little dots. First my thoughts were something like “you just do expr <- expr | expr.expr”. This is just wrong. At least I should have reversed the order as this leads to infinite left recursion. Then I might have got away. Then I realized I only need dots after function calls and simple identifiers. Design choice(if you think it’s a bad one leave a comment). Notice the “simple identifier”. That’s what I did: Renamed identifier to simple identifier and put something that handles dots under name identifier. And then fixed everything.
|
|
That’s about it. At least for parsing. Now the fun begins.
Nesting scopes
Scopes were designed with nesting in mind. This is a double edged sword. See, the “privates” can be done if you rely on not being able to access the parent scope. If dot access exposes full addressing functionality a powerful feature ceases to exist. So some protection should be in place. Something like strict get
|
|
And I also added an unlinked view to it just to ease usage. This is just
a method that returns new SScope with no parent overriding getters and
put to use map available in closure.
So now I can walk down the list in DotAccess recursively and explicitly
override the implicit scope parameter. And everything automagically
works. Well, not quite. If you have a function call, the arguments need
to be evaluated in top scope. Not in the nested one like the function
identifier. At first I didn’t even think about this and only failing
attempts at more complex recursion brought up this quite obvious bug.
So how to solve this? I could pre-evaluate all arguments, but I use
recursion to do this and it’s two levels(at least) deeper from where
dots happen. So no go. I need to carry on the outer scope. I overloaded
the apply method from Evaluator so other code can still function(tests
ftw!) and all in all it looks like this:
|
|
So an optional aux scope is the answer. It doesn’t seem pretty to me, but it does the job.
**next: **trying to go faster
Last modified on 2012-10-08
Previous Making a programming language Part 8 - going fasterNext Javascript faster than light! (well C actually)