Age | Commit message (Collapse) | Author |
|
|
|
|
|
"var" declarations are hoisted to the nearest function scope, while
"let" and "const" are hoisted to the nearest block scope.
This is done by the parser, which keeps two scope stacks, one stack
for the current var scope and one for the current let/const scope.
When the interpreter enters a scope, we walk all of the declarations
and insert them into the variable environment.
We don't support the temporal dead zone for let/const yet.
|
|
|
|
|
|
Many other parsers call it with this name.
Also Type can be confusing in this context since the DeclarationType is
not the type (number, string, etc.) of the variables that are being
declared by the VariableDeclaration.
|
|
This patch only adds the AST node, the parser doesn't create them yet.
|
|
Now that we have two separate storages for Object properties depending
on what kind of index they have, it's nice to have an abstraction that
still allows us to say "here's a property name".
We use PropertyName to always choose the optimal storage path directly
while interpreting the AST. :^)
|
|
|
|
|
|
We were allowing this dangerous kind of thing:
RefPtr<Base> base;
RefPtr<Derived> derived = base;
This patch changes the {Nonnull,}RefPtr constructors so this is no
longer possible.
To downcast one of these pointers, there is now static_ptr_cast<T>:
RefPtr<Derived> derived = static_ptr_cast<Derived>(base);
Fixing this exposed a ton of cowboy-downcasts in various places,
which we're now forced to fix. :^)
|
|
|
|
This patch adds support in the parser and interpreter for this:
var a = 1, b = 2, c = a + b;
VariableDeclaration is now a sequence of VariableDeclarators. :^)
|
|
This is just here to make the AST class hierarchy more spec-like.
|
|
|
|
This name matches other parsers.
|
|
|
|
|
|
There is no such thing as a "undefined literal" in JS - undefined is
just a property on the global object with a value of undefined.
This is pretty similar to NaN.
var undefined = "foo"; is a perfectly fine AssignmentExpression :^)
|
|
|
|
This avoids executing the LHS of the object expression twice when doing
a call on the result of an object expression.
|
|
The "break" keyword now unwinds to the nearest ScopeType::Breakable.
There's no support for break labels yet, but we'll get there too.
|
|
|
|
This operator walks the prototype chain of the RHS value and looks for
a "prototype" property with the same value as the prototype of the LHS.
This is pretty cool. :^)
|
|
NewExpression mostly piggybacks on the existing CallExpression. The big
difference is that "new" creates a new Object and passes it as |this|
to the callee.
|
|
You can now throw an expression to the nearest catcher! :^)
To support throwing arbitrary values, I added an Exception class that
sits as a wrapper around whatever is thrown. In the future it will be
a logical place to store a call stack.
|
|
This is the first step towards support exceptions. :^)
|
|
A bunch of code was relying on this not happenind, in particular the
parsing of "for" statements. Reorganized things so they work again.
|
|
We can now handle scripts with if/else in LibJS. Most of the changes
are about fixing IfStatement to store the consequent and alternate node
as Statements.
Interpreter now also runs Statements, rather than running ScopeNodes.
|
|
This makes variable and property lookups a lot faster since comparing
two FlyStrings is O(1).
|
|
This patch implements basic parsing of "if" statements. We don't yet
support parsing "else", so I added a FIXME about that.
|
|
- move() the property map when constructing ObjectExpression instead of
making a copy.
- Use key+value iterators to traverse the property map in the execute()
and dump() functions.
|
|
|
|
MemberExpression comes in two flavors:
computed: a[b]
non-computed: a.b
We can now parse both of the types. :^)
|
|
Note that property lookup is not functional yet.
|
|
This is pretty naive, we just walk up the prototype chain and call any
NativeProperty setter that we find. If we don't find one, we put/set
the value as an own property of the object itself.
|
|
FunctionExpression is mostly like FunctionDeclaration, except the name
is optional. Share the parsing logic in parse_function_node<NodeType>.
This allows us to do nice things like:
document.addEventListener("DOMContentLoaded", function() {
alert("Hello friends!");
});
|
|
Most of the code is shared with FunctionDeclaration, so the shared bits
are moved up into a common base called FunctionNode.
|
|
Using make<T> like this would create an unadopted object whose refcount
would never reach zero.
|
|
This allows function objects to outlive the original parsed program
without their ScopeNode disappearing.
|
|
|
|
Let's try to keep LibJS tidy as it expands. :^)
|
|
|
|
|
|
|
|
Object will now traverse up the prototype chain when doing a get().
When a function is called on an object, that object will now also be
the "this" value inside the function. This stuff is probably not very
correct, but we will improve things as we go! :^)
|
|
|
|
|
|
We now evaluate for loops in their own scope if their init statement is
a lexical declaration.
Evaluating for loops in their own scope allow us to obtain expected
behaviour, which means for example, that the block-scoped variables
declared in a for statement will be limited to the scope of the for
loop's body and statement and not to that of the current scope (i.e the
one where the for statement was made)
|
|
Obey precedence and associativity rules when parsing expressions
with chained operators.
|