ES6 Support Groundwork + Fixes (OLD ONE DON'T LOOK AT ME!!!) #22

Merged
TopchetoEU merged 49 commits from ES6 into master 2024-09-05 14:17:52 +00:00
9 changed files with 59 additions and 24 deletions
Showing only changes of commit d7353e19ed - Show all commits

View File

@ -352,8 +352,8 @@ public class Instruction {
public static Instruction loadThis() {
return new Instruction(Type.LOAD_THIS);
}
public static Instruction loadArgs() {
return new Instruction(Type.LOAD_ARGS);
public static Instruction loadArgs(boolean real) {
return new Instruction(Type.LOAD_ARGS, real);
}
public static Instruction loadRestArgs(int offset) {
return new Instruction(Type.LOAD_REST_ARGS, offset);

View File

@ -54,17 +54,21 @@ public class FunctionArrowNode extends FunctionNode {
if (!src.is(i + n, "=>")) return ParseRes.failed();
n += 2;
n += Parsing.skipEmpty(src, i + n);
ParseRes<Node> body = ParseRes.first(src, i + n,
(s, j) -> JavaScript.parseExpression(s, j, 2),
CompoundNode::parse
);
if (!body.isSuccess()) return body.chainError(src.loc(i + n), "Expected an expression or a compount statement after '=>'");
n += body.n;
if (src.is(i + n, "{")) {
var body = CompoundNode.parse(src, i + n);
if (!body.isSuccess()) return body.chainError(src.loc(i + n), "Expected a compount statement after '=>'");
n += body.n;
return ParseRes.res(new FunctionArrowNode(
loc, src.loc(i + n - 1),
params, body.result
), n);
return ParseRes.res(new FunctionArrowNode(loc, src.loc(i + n - 1), params, body.result), n);
}
else {
var body = JavaScript.parseExpression(src, i + n, 2);
if (!body.isSuccess()) return body.chainError(src.loc(i + n), "Expected a compount statement after '=>'");
n += body.n;
return ParseRes.res(new FunctionArrowNode(loc, src.loc(i + n - 1), params, body.result), n);
}
}
}

View File

@ -31,12 +31,12 @@ public abstract class FunctionNode extends Node {
.remove(LabelContext.CONTINUE_CTX);
return new CompileResult(env, scope, params.params.size(), target -> {
if (hasArgs || params.params.size() > 0) target.add(Instruction.loadArgs());
if (hasArgs || params.params.size() > 0) target.add(Instruction.loadArgs(true));
if (hasArgs) {
var argsVar = scope.defineStrict(new Variable("arguments", true), loc());
target.add(_i -> Instruction.storeVar(argsVar.index(), params.params.size() > 0));
}
// if (hasArgs) {
// var argsVar = scope.defineStrict(new Variable("arguments", true), loc());
// target.add(_i -> Instruction.storeVar(argsVar.index(), params.params.size() > 0));
// }
if (params.params.size() > 0) {
if (params.params.size() > 1) target.add(Instruction.dup(params.params.size() - 1));

View File

@ -24,6 +24,7 @@ import me.topchetoeu.jscript.compilation.control.ThrowNode;
import me.topchetoeu.jscript.compilation.control.TryNode;
import me.topchetoeu.jscript.compilation.control.WhileNode;
import me.topchetoeu.jscript.compilation.scope.FunctionScope;
import me.topchetoeu.jscript.compilation.values.ArgumentsNode;
import me.topchetoeu.jscript.compilation.values.ArrayNode;
import me.topchetoeu.jscript.compilation.values.ObjectNode;
import me.topchetoeu.jscript.compilation.values.RegexNode;
@ -60,7 +61,7 @@ public final class JavaScript {
"finally", "for", "do", "while", "switch", "case", "default", "new",
"function", "var", "return", "throw", "typeof", "delete", "break",
"continue", "debugger", "implements", "interface", "package", "private",
"protected", "public", "static"
"protected", "public", "static", "arguments"
);
public static ParseRes<? extends Node> parseParens(Source src, int i) {
@ -115,7 +116,7 @@ public final class JavaScript {
if (id.result.equals("false")) return ParseRes.res(new BoolNode(loc, false), n);
if (id.result.equals("null")) return ParseRes.res(new NullNode(loc), n);
if (id.result.equals("this")) return ParseRes.res(new ThisNode(loc), n);
// if (id.result.equals("arguments")) return ParseRes.res(new ArgumentsNode(loc), n);
if (id.result.equals("arguments")) return ParseRes.res(new ArgumentsNode(loc), n);
return ParseRes.failed();
}

View File

@ -0,0 +1,17 @@
package me.topchetoeu.jscript.compilation.values;
import me.topchetoeu.jscript.common.Instruction;
import me.topchetoeu.jscript.common.parsing.Location;
import me.topchetoeu.jscript.compilation.CompileResult;
import me.topchetoeu.jscript.compilation.Node;
public class ArgumentsNode extends Node {
@Override public void compile(CompileResult target, boolean pollute) {
if (pollute) target.add(Instruction.loadArgs(false));
}
public ArgumentsNode(Location loc) {
super(loc);
}
}

View File

@ -13,6 +13,7 @@ import me.topchetoeu.jscript.common.parsing.Source;
import me.topchetoeu.jscript.compilation.CompileResult;
import me.topchetoeu.jscript.compilation.JavaScript;
import me.topchetoeu.jscript.compilation.Node;
import me.topchetoeu.jscript.compilation.values.ArgumentsNode;
import me.topchetoeu.jscript.compilation.values.ArrayNode;
import me.topchetoeu.jscript.compilation.values.ObjectNode;
import me.topchetoeu.jscript.compilation.values.ThisNode;
@ -55,6 +56,9 @@ public class CallNode extends Node {
else if (func instanceof ThisNode) {
res = "this";
}
else if (func instanceof ArgumentsNode) {
res = "arguments";
}
else if (func instanceof ArrayNode) {
var els = new ArrayList<String>();

View File

@ -101,8 +101,9 @@ public final class Frame {
*/
public final Value[][] captures;
public final List<Value[]> locals = new ArrayList<>();
public final Value self;
public final Value argsVal;
public Value self;
public Value fakeArgs;
public final Value[] args;
public final boolean isNew;
public final Stack<TryCtx> tryStack = new Stack<>();

View File

@ -185,7 +185,10 @@ public class InstructionRunner {
var func = new CodeFunction(env, name, frame.function.body.children[id], captures);
if (!callable) func.enableCall = false;
if (!constructible) func.enableNew = false;
if (captureThis) func.self = frame.self;
if (captureThis) {
func.self = frame.self;
func.argsVal = frame.argsVal;
}
frame.push(func);
frame.codePtr++;
@ -472,7 +475,8 @@ public class InstructionRunner {
}
private static Value execLoadArgs(Environment env, Instruction instr, Frame frame) {
frame.push(frame.argsVal);
if ((boolean)instr.get(0) || frame.fakeArgs == null) frame.push(frame.argsVal);
else frame.push(frame.fakeArgs);
frame.codePtr++;
return null;
}

View File

@ -9,6 +9,7 @@ public final class CodeFunction extends FunctionValue {
public final FunctionBody body;
public final Value[][] captures;
public Value self;
public Value argsVal;
public Environment env;
private Value onCall(Frame frame) {
@ -26,8 +27,11 @@ public final class CodeFunction extends FunctionValue {
}
@Override public Value onCall(Environment env, boolean isNew, String name, Value thisArg, Value ...args) {
if (self != null) return onCall(new Frame(env, isNew, self, args, this));
else return onCall(new Frame(env, isNew, thisArg, args, this));
var frame = new Frame(env, isNew, thisArg, args, this);
if (argsVal != null) frame.fakeArgs = argsVal;
if (self != null) frame.self = self;
return onCall(frame);
}
public CodeFunction(Environment env, String name, FunctionBody body, Value[][] captures) {