ES6 Support Groundwork + Fixes (OLD ONE DON'T LOOK AT ME!!!) #22
@ -352,8 +352,8 @@ public class Instruction {
|
|||||||
public static Instruction loadThis() {
|
public static Instruction loadThis() {
|
||||||
return new Instruction(Type.LOAD_THIS);
|
return new Instruction(Type.LOAD_THIS);
|
||||||
}
|
}
|
||||||
public static Instruction loadArgs() {
|
public static Instruction loadArgs(boolean real) {
|
||||||
return new Instruction(Type.LOAD_ARGS);
|
return new Instruction(Type.LOAD_ARGS, real);
|
||||||
}
|
}
|
||||||
public static Instruction loadRestArgs(int offset) {
|
public static Instruction loadRestArgs(int offset) {
|
||||||
return new Instruction(Type.LOAD_REST_ARGS, offset);
|
return new Instruction(Type.LOAD_REST_ARGS, offset);
|
||||||
|
@ -54,17 +54,21 @@ public class FunctionArrowNode extends FunctionNode {
|
|||||||
|
|
||||||
if (!src.is(i + n, "=>")) return ParseRes.failed();
|
if (!src.is(i + n, "=>")) return ParseRes.failed();
|
||||||
n += 2;
|
n += 2;
|
||||||
|
n += Parsing.skipEmpty(src, i + n);
|
||||||
|
|
||||||
ParseRes<Node> body = ParseRes.first(src, i + n,
|
if (src.is(i + n, "{")) {
|
||||||
(s, j) -> JavaScript.parseExpression(s, j, 2),
|
var body = CompoundNode.parse(src, i + n);
|
||||||
CompoundNode::parse
|
if (!body.isSuccess()) return body.chainError(src.loc(i + n), "Expected a compount statement after '=>'");
|
||||||
);
|
n += body.n;
|
||||||
if (!body.isSuccess()) return body.chainError(src.loc(i + n), "Expected an expression or a compount statement after '=>'");
|
|
||||||
n += body.n;
|
|
||||||
|
|
||||||
return ParseRes.res(new FunctionArrowNode(
|
return ParseRes.res(new FunctionArrowNode(loc, src.loc(i + n - 1), params, body.result), n);
|
||||||
loc, src.loc(i + n - 1),
|
}
|
||||||
params, body.result
|
else {
|
||||||
), n);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,12 +31,12 @@ public abstract class FunctionNode extends Node {
|
|||||||
.remove(LabelContext.CONTINUE_CTX);
|
.remove(LabelContext.CONTINUE_CTX);
|
||||||
|
|
||||||
return new CompileResult(env, scope, params.params.size(), target -> {
|
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) {
|
// if (hasArgs) {
|
||||||
var argsVar = scope.defineStrict(new Variable("arguments", true), loc());
|
// var argsVar = scope.defineStrict(new Variable("arguments", true), loc());
|
||||||
target.add(_i -> Instruction.storeVar(argsVar.index(), params.params.size() > 0));
|
// target.add(_i -> Instruction.storeVar(argsVar.index(), params.params.size() > 0));
|
||||||
}
|
// }
|
||||||
|
|
||||||
if (params.params.size() > 0) {
|
if (params.params.size() > 0) {
|
||||||
if (params.params.size() > 1) target.add(Instruction.dup(params.params.size() - 1));
|
if (params.params.size() > 1) target.add(Instruction.dup(params.params.size() - 1));
|
||||||
|
@ -24,6 +24,7 @@ import me.topchetoeu.jscript.compilation.control.ThrowNode;
|
|||||||
import me.topchetoeu.jscript.compilation.control.TryNode;
|
import me.topchetoeu.jscript.compilation.control.TryNode;
|
||||||
import me.topchetoeu.jscript.compilation.control.WhileNode;
|
import me.topchetoeu.jscript.compilation.control.WhileNode;
|
||||||
import me.topchetoeu.jscript.compilation.scope.FunctionScope;
|
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.ArrayNode;
|
||||||
import me.topchetoeu.jscript.compilation.values.ObjectNode;
|
import me.topchetoeu.jscript.compilation.values.ObjectNode;
|
||||||
import me.topchetoeu.jscript.compilation.values.RegexNode;
|
import me.topchetoeu.jscript.compilation.values.RegexNode;
|
||||||
@ -60,7 +61,7 @@ public final class JavaScript {
|
|||||||
"finally", "for", "do", "while", "switch", "case", "default", "new",
|
"finally", "for", "do", "while", "switch", "case", "default", "new",
|
||||||
"function", "var", "return", "throw", "typeof", "delete", "break",
|
"function", "var", "return", "throw", "typeof", "delete", "break",
|
||||||
"continue", "debugger", "implements", "interface", "package", "private",
|
"continue", "debugger", "implements", "interface", "package", "private",
|
||||||
"protected", "public", "static"
|
"protected", "public", "static", "arguments"
|
||||||
);
|
);
|
||||||
|
|
||||||
public static ParseRes<? extends Node> parseParens(Source src, int i) {
|
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("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("null")) return ParseRes.res(new NullNode(loc), n);
|
||||||
if (id.result.equals("this")) return ParseRes.res(new ThisNode(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();
|
return ParseRes.failed();
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
@ -13,6 +13,7 @@ import me.topchetoeu.jscript.common.parsing.Source;
|
|||||||
import me.topchetoeu.jscript.compilation.CompileResult;
|
import me.topchetoeu.jscript.compilation.CompileResult;
|
||||||
import me.topchetoeu.jscript.compilation.JavaScript;
|
import me.topchetoeu.jscript.compilation.JavaScript;
|
||||||
import me.topchetoeu.jscript.compilation.Node;
|
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.ArrayNode;
|
||||||
import me.topchetoeu.jscript.compilation.values.ObjectNode;
|
import me.topchetoeu.jscript.compilation.values.ObjectNode;
|
||||||
import me.topchetoeu.jscript.compilation.values.ThisNode;
|
import me.topchetoeu.jscript.compilation.values.ThisNode;
|
||||||
@ -55,6 +56,9 @@ public class CallNode extends Node {
|
|||||||
else if (func instanceof ThisNode) {
|
else if (func instanceof ThisNode) {
|
||||||
res = "this";
|
res = "this";
|
||||||
}
|
}
|
||||||
|
else if (func instanceof ArgumentsNode) {
|
||||||
|
res = "arguments";
|
||||||
|
}
|
||||||
else if (func instanceof ArrayNode) {
|
else if (func instanceof ArrayNode) {
|
||||||
var els = new ArrayList<String>();
|
var els = new ArrayList<String>();
|
||||||
|
|
||||||
|
@ -101,8 +101,9 @@ public final class Frame {
|
|||||||
*/
|
*/
|
||||||
public final Value[][] captures;
|
public final Value[][] captures;
|
||||||
public final List<Value[]> locals = new ArrayList<>();
|
public final List<Value[]> locals = new ArrayList<>();
|
||||||
public final Value self;
|
|
||||||
public final Value argsVal;
|
public final Value argsVal;
|
||||||
|
public Value self;
|
||||||
|
public Value fakeArgs;
|
||||||
public final Value[] args;
|
public final Value[] args;
|
||||||
public final boolean isNew;
|
public final boolean isNew;
|
||||||
public final Stack<TryCtx> tryStack = new Stack<>();
|
public final Stack<TryCtx> tryStack = new Stack<>();
|
||||||
|
@ -185,7 +185,10 @@ public class InstructionRunner {
|
|||||||
var func = new CodeFunction(env, name, frame.function.body.children[id], captures);
|
var func = new CodeFunction(env, name, frame.function.body.children[id], captures);
|
||||||
if (!callable) func.enableCall = false;
|
if (!callable) func.enableCall = false;
|
||||||
if (!constructible) func.enableNew = 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.push(func);
|
||||||
|
|
||||||
frame.codePtr++;
|
frame.codePtr++;
|
||||||
@ -472,7 +475,8 @@ public class InstructionRunner {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static Value execLoadArgs(Environment env, Instruction instr, Frame frame) {
|
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++;
|
frame.codePtr++;
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@ public final class CodeFunction extends FunctionValue {
|
|||||||
public final FunctionBody body;
|
public final FunctionBody body;
|
||||||
public final Value[][] captures;
|
public final Value[][] captures;
|
||||||
public Value self;
|
public Value self;
|
||||||
|
public Value argsVal;
|
||||||
public Environment env;
|
public Environment env;
|
||||||
|
|
||||||
private Value onCall(Frame frame) {
|
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) {
|
@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));
|
var frame = new Frame(env, isNew, thisArg, args, this);
|
||||||
else return onCall(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) {
|
public CodeFunction(Environment env, String name, FunctionBody body, Value[][] captures) {
|
||||||
|
Loading…
Reference in New Issue
Block a user