Age | Commit message (Collapse) | Author |
|
I'm not sure how this even _builds_
|
|
This (seemingly) no-op cast communicates our intention to clang
|
|
|
|
|
|
|
|
|
|
The ECMAScript spec defines multiple equality operations which are used
all over the spec; this patch introduces them. Of course, the two
primary equality operations are AbtractEquals ('==') and StrictEquals
('==='), which have been renamed to 'abstract_eq' and 'strict_eq' in
this patch.
In support of the two operations mentioned above, the following have
also been added: SameValue, SameValueZero, and SameValueNonNumeric.
These are important to have, because they are used elsewhere in the spec
aside from the two primary equality comparisons.
|
|
This required 2 changes:
1. In the parser, create a new variable scope, so the variable is
declared in it instead of the scope in which the 'for' is found.
2. On execute, push the variable into the newly created block. Existing
code created an empty block (no variables, no arguments) which
allows Interpreter::enter_scope() to skip the creation of a new
environment, therefore when the variable initializer is executed, it
sets the variable to the outer scope. By attaching the variable to
the new block, the block gets a new environment.
This is only needed for 'let' / 'const' declarations, since 'var'
declarations are expected to leak.
Fixes: #2103
|
|
|
|
When calling a function with a tagged template, the first array that is
passed in now contains a "raw" property with the raw, escaped strings.
|
|
|
|
Adds support for the following syntax:
myFunction(...x, ...[1, 2, 3], ...o.foo, ...'abcd')
|
|
"[Function.length is] the number of formal parameters. This number
excludes the rest parameter and only includes parameters before
the first one with a default value." - MDN
|
|
|
|
To make processing tagged template literals easier, template literals
will now add one empty StringLiteral before and after each template
expression *if* there's no other string - e.g.:
`${foo}` -> "", foo, ""
`test${foo}${bar}test` -> "test", foo, "", bar, "test"
This also matches the behaviour of many other parsers.
|
|
|
|
A regression was introduced in dc9b4da where the parser would
incorrectly parse the assignment of arrow functions to (non-declaration)
variables. For example, consider:
a = () => {}
Because the parser was aware of default parameters, in
try_parse_arrow_function, the equals sign would be interpreted as a
default argument, leading to incorrect parsing of the overall
expression. Also resulted in some funny behavior
(a = () => {} => {} worked just fine!).
The simple fix is to only look for default parameters if the arrow
function is required to have parenthesis.
|
|
At that point, it seems unlikely that the shape is gonna be shared with
other objects, and we avoid getting stuck holding a big bag of shapes.
|
|
|
|
|
|
|
|
|
|
Now, you can optionally specify a ConsoleClient, to customise the
behaviour of the LibJS Console.
To customise the console, create a new ConsoleClient class that inherits
from JS::ConsoleClient and override all the abstract methods.
When Console::log() is called, if Console has a ConsoleClient,
ConsoleClient::log() is called instead.
These abstract methods are Value(void) functions: you can return a Value
which will be returned by the JavaScript function which calls that
method, in JavaScript.
|
|
Also add const overloads for some getters.
Also const-qualify Interpreter::join_arguments().
|
|
|
|
Console methods are now Value(void) functions.
JavaScript functions in the JavaScript ConsoleObject are now implemented
as simple wrappers around Console methods.
This will make it possible for LibJS users to easily override the
default behaviour of JS console functions (even their return value!)
once we add a way to override Console behaviour.
|
|
It can be useful outside of Runtime/ConsoleObject.cpp.
join_args() => Interpreter::join_arguments()
|
|
We don't need to store the past messages in LibJS.
We'll implement a way to let LibJS users expand the vanilla Console.
|
|
|
|
This now matches the output of
Program
(Variables)
...
(Children)
...
or
FunctionDeclaration 'foo'
(Parameters)
...
(Body)
...
etc.
Also don't print each consequent statement index, it doesn't add any
value.
|
|
Adds fully functioning template literals. Because template literals
contain expressions, most of the work has to be done in the Lexer rather
than the Parser. And because of the complexity of template literals
(expressions, nesting, escapes, etc), the Lexer needs to have some
template-related state.
When entering a new template literal, a TemplateLiteralStart token is
emitted. When inside a literal, all text will be parsed up until a '${'
or '`' (or EOF, but that's a syntax error) is seen, and then a
TemplateLiteralExprStart token is emitted. At this point, the Lexer
proceeds as normal, however it keeps track of the number of opening
and closing curly braces it has seen in order to determine the close
of the expression. Once it finds a matching curly brace for the '${',
a TemplateLiteralExprEnd token is emitted and the state is updated
accordingly.
When the Lexer is inside of a template literal, but not an expression,
and sees a '`', this must be the closing grave: a TemplateLiteralEnd
token is emitted.
The state required to correctly parse template strings consists of a
vector (for nesting) of two pieces of information: whether or not we
are in a template expression (as opposed to a template string); and
the count of the number of unmatched open curly braces we have seen
(only applicable if the Lexer is currently in a template expression).
TODO: Add support for template literal newlines in the JS REPL (this will
cause a syntax error currently):
> `foo
> bar`
'foo
bar'
|
|
We already skipped random semicolons in Parser::parse_program(), but now
they are properly matched and parsed as empty statements - and thus
recognized as a valid body of an if / else / while / ... statement.
|
|
|
|
Adds the ability for function arguments to have default values. This
works for standard functions as well as arrow functions. Default values
are not printed in a <function>.toString() call, as nodes cannot print
their source string representation.
|
|
|
|
|
|
|
|
|
|
...as it is supposed to be.
|
|
A ConsoleMessage is a struct cointaining:
* AK::String text; represents the text of the message sent
to the console.
* ConsoleMessageKind kind; represents the kind of JS `console` function
from which the message was sent.
Now, Javascript `console` functions only send a ConsoleMessage to the
Interpreter's Console instead of printing text directly to stdout.
The Console then stores the recived ConsoleMessage in
Console::m_messages; the Console does not print to stdout by default.
You can set Console::on_new_message to a void(ConsoleMessage&); this
function will get call everytime a new message is added to the Console's
messages and can be used, for example, to print ConsoleMessages to
stdout or to color the output based on the kind of ConsoleMessage.
In this patch, I also:
* Re-implement all the previously implemented functions in the
JavaScript ConsoleObject, as wrappers around Console functions
that add new message to the Console.
* Implement console.clear() like so:
- m_messages get cleared;
- a new_message with kind set ConsoleMessageKind::Clear gets added
to m_messages, its text is an empty AK::String;
* Give credit to linusg in Console.cpp since I used his
console.trace() algorithm in Console::trace().
I think that having this abstration will help us in the implementation
of a browser console or a JS debugger. We could also add more MetaData
to ConsoleMessage, e.g. Object IDs of the arguments passed to console
functions in order to make hyperlinks, Timestamps, ecc.; which could be
interesting to see.
This will also help in implementing a `/bin/js` option to make, for
example, return a ConsoleMessageWrapper to console functions instead of
undefined. This will be useful to make tests for functions like
console.count() and console.countClear(). :^)
|
|
Also implement ConsoleObject::count_clear() as a wrapper for
Console::count_clear()
|
|
The goal is to start factoring out core ConsoleObject functionality and
to make ConsoleObject only a JS wrapper around Console.
|
|
|
|
|
|
|
|
This was incorrect, it's only writable.
|
|
|
|
Like Object::has_own_property() but going down the prototype chain.
|
|
|
|
|