Commit graph

138 commits

Author SHA1 Message Date
Linus Groh
43c1fa9965 LibJS: Implement (no-op) debugger statement 2020-05-01 22:07:13 +02:00
mattco98
104969a9f5 LibJS: Add spreading in object literals
Supports spreading strings, arrays, and other objects within object
literals.
2020-04-28 20:37:21 +02:00
Andreas Kling
ee0bf55127 LibJS: Make AssignmentExpression assign through a Reference
Reference now has assign(Interpreter&, Value) which is used to write
transparently through a Reference into whatever location it refers to.
2020-04-28 15:07:08 +02:00
Andreas Kling
3c4a9e421f LibJS: Allow "delete someGlobalVariable"
This is solved by allowing Identifier nodes to produce a Reference with
the global object as base.
2020-04-28 15:07:08 +02:00
Andreas Kling
67b8e6fc5b LibJS: Add Reference class to represent a base.property reference
Expression nodes can now be asked to produce a Reference. We then use
this to implement the "delete" operator without downcasting the child
node to a MemberExpression manually.
2020-04-28 15:07:08 +02:00
mattco98
80fecc615a LibJS: Add spreading in array literals
Implement the syntax and behavor necessary to support array literals
such as [...[1, 2, 3]]. A type error is thrown if the target of the
spread operator does not evaluate to an array (though it should
eventually just check for an iterable).

Note that the spread token's name is TripleDot, since the '...' token is
used for two features: spread and rest. Calling it anything involving
'spread' or 'rest' would be a bit confusing.
2020-04-27 11:32:18 +02:00
Andreas Kling
f897c41092 LibJS: Implement basic support for the "delete" operator
It turns out "delete" is actually a unary op :)
This patch implements deletion of object properties, it doesn't yet
work for casually deleting properties from the global object.

When deleting a property from an object, we switch that object to
having a unique shape, no longer sharing shapes with others.
Once an object has a unique shape, it no longer needs to care about
shape transitions.
2020-04-26 15:51:07 +02:00
Linus Groh
746dd5b190 LibJS: Implement computed properties in object expressions 2020-04-23 23:56:04 +02:00
Linus Groh
11728b7db5 LibJS: Implement 'in' operator 2020-04-23 19:38:13 +02:00
Linus Groh
396ecfa2d7 LibJS: Implement bitwise unsigned right shift operator (>>>) 2020-04-23 19:38:13 +02:00
Linus Groh
502d1f5165 LibJS: Implement bitwise right shift operator (>>) 2020-04-23 19:38:13 +02:00
Linus Groh
f0e7404480 LibJS: Implement bitwise left shift operator (<<) 2020-04-23 19:38:13 +02:00
Linus Groh
03f2024b6e LibJS: Improve CallExpression::execute()'s error messages 2020-04-19 11:00:39 +02:00
Linus Groh
d14ddb6461 LibJS: Implement nullish coalescing operator (??) 2020-04-18 12:34:13 +02:00
Linus Groh
cea950fd70 LibJS: Support empty values in array expression 2020-04-15 21:23:06 +02:00
Linus Groh
d30db07048 LibJS: Implement void operator 2020-04-15 19:12:51 +02:00
Andreas Kling
ac7459cb40 LibJS: Hoist variable declarations to the nearest relevant scope
"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.
2020-04-13 17:22:23 +02:00
Stephan Unverwerth
f8f65053bd LibJS: Parse "this" as ThisExpression 2020-04-13 00:45:25 +02:00
Linus Groh
eece424694 LibJS: Make Function and CallFrame aware of their function name 2020-04-11 14:10:42 +02:00
Emanuele Torre
38dfd04633 LibJS: rename JS::DeclarationType => JS::DeclarationKind
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.
2020-04-08 14:50:14 +02:00
Andreas Kling
19cbfaee54 LibJS: Add SequenceExpression AST node (comma operator)
This patch only adds the AST node, the parser doesn't create them yet.
2020-04-07 15:56:26 +02:00
Andreas Kling
be019f28ca LibJS: Add a PropertyName class that represents a string or a number
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. :^)
2020-04-06 18:09:26 +02:00
Linus Groh
0403845d3e LibJS: Implement exponentiation (** operator) 2020-04-05 15:32:06 +02:00
Linus Groh
eafd3dbaf8 LibJS: Rename BinaryOp::{Plus,Minus,Asterisk,Slash} 2020-04-05 15:31:12 +02:00
Andreas Kling
1d468ed6d3 AK: Stop allowing implicit downcast with RefPtr and NonnullRefPtr
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. :^)
2020-04-05 11:19:00 +02:00
Andreas Kling
9ebd066ac8 LibJS: Add support for "continue" inside "for" statements :^) 2020-04-05 00:22:42 +02:00
Andreas Kling
5e40aa182b LibJS: Support VariableDeclaration with multiple declarators
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. :^)
2020-04-04 21:47:12 +02:00
Andreas Kling
9691286cf0 LibJS: Add Declaration class to the AST
This is just here to make the AST class hierarchy more spec-like.
2020-04-04 21:32:10 +02:00
Andreas Kling
f8393b80e3 LibJS: Add support for do..while statements 2020-04-04 21:29:23 +02:00
Andreas Kling
da0715aba9 LibJS: Rename WhileStatement::predicate() => body()
This name matches other parsers.
2020-04-04 21:22:03 +02:00
Andreas Kling
644ff1bbfd LibJS: Add basic support for modulo (%) in binary expressions 2020-04-04 21:17:34 +02:00
Andreas Kling
0622181d1f LibJS: Implement ConditionalExpression (ternary "?:" operator) 2020-04-03 12:15:14 +02:00
Linus Groh
2636cac6e4 LibJS: Remove UndefinedLiteral, add undefined to global object
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 :^)
2020-04-03 00:10:52 +02:00
Linus Groh
a62230770b LibJS: Implement unary plus / minus 2020-04-02 19:55:45 +02:00
Andreas Kling
cd9379dca9 LibJS: Reorganize computing of |this| for CallExpressions
This avoids executing the LHS of the object expression twice when doing
a call on the result of an object expression.
2020-04-01 18:57:00 +02:00
Andreas Kling
2285f84596 LibJS: Implement basic execution of "switch" statements
The "break" keyword now unwinds to the nearest ScopeType::Breakable.
There's no support for break labels yet, but we'll get there too.
2020-03-29 15:03:58 +02:00
Andreas Kling
1923051c5b LibJS: Lexer and parser support for "switch" statements 2020-03-29 15:03:58 +02:00
Andreas Kling
a3d92b1210 LibJS: Implement the "instanceof" operator
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. :^)
2020-03-28 16:56:54 +01:00
Andreas Kling
0593ce406b LibJS: Implement basic support for the "new" keyword
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.
2020-03-28 16:33:52 +01:00
Andreas Kling
faddf3a1db LibJS: Implement "throw"
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.
2020-03-24 22:21:58 +01:00
Andreas Kling
c33d4aefc3 LibJS: Parse "try", "catch" and "finally"
This is the first step towards support exceptions. :^)
2020-03-24 16:14:10 +01:00
Andreas Kling
df524203b2 LibJS: Consume semicolon at the end of a statement
A bunch of code was relying on this not happenind, in particular the
parsing of "for" statements. Reorganized things so they work again.
2020-03-23 19:10:18 +01:00
Andreas Kling
fbb9e1b715 LibJS: Implement "else" parsing
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.
2020-03-23 16:52:58 +01:00
Andreas Kling
cccbe43056 LibJS: Use FlyString for identifiers
This makes variable and property lookups a lot faster since comparing
two FlyStrings is O(1).
2020-03-22 13:03:43 +01:00
Andreas Kling
7c48c3c8e1 LibJS: Parse "if" statements
This patch implements basic parsing of "if" statements. We don't yet
support parsing "else", so I added a FIXME about that.
2020-03-21 18:40:17 +01:00
Andreas Kling
00feef8642 LibJS: Some optimizations for ObjectExpression
- 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.
2020-03-21 13:11:51 +01:00
0xtechnobabble
bc002f807a LibJS: Parse object expressions 2020-03-21 10:08:58 +01:00
Andreas Kling
a3d2e07446 LibJS: Parse computed MemberExpressions
MemberExpression comes in two flavors:

    computed: a[b]
non-computed: a.b

We can now parse both of the types. :^)
2020-03-20 21:56:40 +01:00
Andreas Kling
a82f64d3d6 LibJS: Parse ArrayExpression and start implementing Array objects
Note that property lookup is not functional yet.
2020-03-20 21:56:40 +01:00
Andreas Kling
1a10470c1d LibJS: Implement basic object property assignment
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.
2020-03-19 17:44:06 +01:00