diff --git a/src/main/java/me/topchetoeu/jscript/compilation/FunctionNode.java b/src/main/java/me/topchetoeu/jscript/compilation/FunctionNode.java index b4a53b1..38da50a 100644 --- a/src/main/java/me/topchetoeu/jscript/compilation/FunctionNode.java +++ b/src/main/java/me/topchetoeu/jscript/compilation/FunctionNode.java @@ -1,5 +1,7 @@ package me.topchetoeu.jscript.compilation; +import java.util.List; + import me.topchetoeu.jscript.common.Instruction; import me.topchetoeu.jscript.common.Instruction.BreakpointType; import me.topchetoeu.jscript.common.environment.Environment; @@ -7,65 +9,49 @@ import me.topchetoeu.jscript.common.parsing.Location; import me.topchetoeu.jscript.common.parsing.ParseRes; import me.topchetoeu.jscript.common.parsing.Parsing; import me.topchetoeu.jscript.common.parsing.Source; -import me.topchetoeu.jscript.compilation.JavaScript.DeclarationType; import me.topchetoeu.jscript.compilation.scope.FunctionScope; -import me.topchetoeu.jscript.compilation.scope.Variable; +import me.topchetoeu.jscript.compilation.values.VariableNode; public abstract class FunctionNode extends Node { public final CompoundNode body; - public final Parameters params; + public final List params; public final Location end; public abstract String name(); + public final String name(String fallback) { + return this.name() != null ? this.name() : fallback; + } protected final int[] captures(int id, CompileResult target) { - return ((FunctionScope)target.children.get(id).scope).getCaptureIndices(); + return target.children.get(id).scope.getCaptureIndices(); } - protected void compilePreBody(CompileResult target) { } - - protected Environment rootEnv(Environment env) { + protected final Environment rootEnv(Environment env) { return env.get(JavaScript.COMPILE_ROOT); } public final CompileResult compileBody(Environment env, FunctionScope scope, boolean lastReturn, String _name, String selfName) { - var name = this.name() != null ? this.name() : _name; + var target = new CompileResult(env, scope, params.size()); + var i = 0; - return new CompileResult(env, scope, params.params.size(), target -> { - compilePreBody(target); + for (var param : params) { + var index = scope.define(param.name); - if (params.params.size() > 0) { - target.add(Instruction.loadArgs(true)); - if (params.params.size() > 1) target.add(Instruction.dup(params.params.size() - 1, 0)); - var i = 0; + target.add(Instruction.loadArg(i++)); + target.add(index.index().toInit()); + } - for (var param : params.params) { - target.add(Instruction.loadMember(i++)); - param.destruct(target, DeclarationType.VAR, true); - } - } + // if (selfName != null && !scope.has(selfName, false)) { + // var i = scope.defineSpecial(new Variable(selfName, true), end); - if (params.rest != null) { - target.add(Instruction.loadRestArgs(params.params.size())); - params.rest.destruct(target, DeclarationType.VAR, true); - } + // target.add(Instruction.loadCalled()); + // target.add(_i -> i.index().toInit()); + // } - if (selfName != null && !scope.has(name, false)) { - var i = scope.defineSpecial(new Variable(selfName, true), end); + body.resolve(target); + body.compile(target, lastReturn, BreakpointType.NONE); - target.add(Instruction.loadCallee()); - target.add(_i -> i.index().toInit()); - } - - body.resolve(target); - body.compile(target, lastReturn, BreakpointType.NONE); - - scope.end(); - - for (var child : target.children) child.buildTask.run(); - - scope.finish(); - }); + return target; } public final CompileResult compileBody(CompileResult parent, String name, String selfName) { return compileBody(rootEnv(parent.env).child(), new FunctionScope(parent.scope), false, name, selfName); @@ -82,13 +68,12 @@ public abstract class FunctionNode extends Node { compile(target, pollute, (String)null, BreakpointType.NONE); } - public FunctionNode(Location loc, Location end, Parameters params, CompoundNode body) { + public FunctionNode(Location loc, Location end, List params, CompoundNode body) { super(loc); this.end = end; this.params = params; this.body = body; - this.body.hasScope = false; } public static void compileWithName(Node stm, CompileResult target, boolean pollute, String name) { @@ -112,7 +97,7 @@ public abstract class FunctionNode extends Node { n += name.n; n += Parsing.skipEmpty(src, i + n); - var params = Parameters.parseParameters(src, i + n); + var params = JavaScript.parseParameters(src, i + n); if (!params.isSuccess()) return params.chainError(src.loc(i + n), "Expected a parameter list"); n += params.n; diff --git a/src/main/java/me/topchetoeu/jscript/compilation/FunctionStatementNode.java b/src/main/java/me/topchetoeu/jscript/compilation/FunctionStatementNode.java index abaee3e..698f3dd 100644 --- a/src/main/java/me/topchetoeu/jscript/compilation/FunctionStatementNode.java +++ b/src/main/java/me/topchetoeu/jscript/compilation/FunctionStatementNode.java @@ -1,5 +1,7 @@ package me.topchetoeu.jscript.compilation; +import java.util.List; + import me.topchetoeu.jscript.common.Instruction; import me.topchetoeu.jscript.common.Instruction.BreakpointType; import me.topchetoeu.jscript.common.parsing.Location; @@ -12,17 +14,17 @@ public class FunctionStatementNode extends FunctionNode { @Override public String name() { return name; } @Override public void resolve(CompileResult target) { - target.scope.define(new Variable(name, false), end); + target.scope.define(new Variable(name, false)); } @Override public void compile(CompileResult target, boolean pollute, String name, BreakpointType bp) { var id = target.addChild(compileBody(target, name, null)); - target.add(_i -> Instruction.loadFunc(id, true, true, false, false, name, captures(id, target))); + target.add(Instruction.loadFunc(id, name, captures(id, target))); target.add(VariableNode.toInit(target, end, this.name)); if (pollute) target.add(Instruction.pushUndefined()); } - public FunctionStatementNode(Location loc, Location end, Parameters params, CompoundNode body, String name) { + public FunctionStatementNode(Location loc, Location end, List params, CompoundNode body, String name) { super(loc, end, params, body); this.name = name; } diff --git a/src/main/java/me/topchetoeu/jscript/compilation/FunctionValueNode.java b/src/main/java/me/topchetoeu/jscript/compilation/FunctionValueNode.java index cf30f75..3d5794a 100644 --- a/src/main/java/me/topchetoeu/jscript/compilation/FunctionValueNode.java +++ b/src/main/java/me/topchetoeu/jscript/compilation/FunctionValueNode.java @@ -1,8 +1,11 @@ package me.topchetoeu.jscript.compilation; +import java.util.List; + import me.topchetoeu.jscript.common.Instruction; import me.topchetoeu.jscript.common.Instruction.BreakpointType; import me.topchetoeu.jscript.common.parsing.Location; +import me.topchetoeu.jscript.compilation.values.VariableNode; public class FunctionValueNode extends FunctionNode { public final String name; @@ -10,11 +13,11 @@ public class FunctionValueNode extends FunctionNode { @Override public String name() { return name; } @Override public void compile(CompileResult target, boolean pollute, String name, BreakpointType bp) { - var id = target.addChild(compileBody(target, name, null)); - target.add(_i -> Instruction.loadFunc(id, true, true, false, false, name, captures(id, target))); + var id = target.addChild(compileBody(target, name, name)); + target.add(Instruction.loadFunc(id, name, captures(id, target))); } - public FunctionValueNode(Location loc, Location end, Parameters params, CompoundNode body, String name) { + public FunctionValueNode(Location loc, Location end, List params, CompoundNode body, String name) { super(loc, end, params, body); this.name = name; } diff --git a/src/main/java/me/topchetoeu/jscript/compilation/VariableDeclareNode.java b/src/main/java/me/topchetoeu/jscript/compilation/VariableDeclareNode.java index 85e3d0f..de32404 100644 --- a/src/main/java/me/topchetoeu/jscript/compilation/VariableDeclareNode.java +++ b/src/main/java/me/topchetoeu/jscript/compilation/VariableDeclareNode.java @@ -3,58 +3,40 @@ package me.topchetoeu.jscript.compilation; import java.util.ArrayList; import java.util.List; +import com.github.bsideup.jabel.Desugar; + import me.topchetoeu.jscript.common.Instruction; import me.topchetoeu.jscript.common.parsing.Location; import me.topchetoeu.jscript.common.parsing.ParseRes; import me.topchetoeu.jscript.common.parsing.Parsing; import me.topchetoeu.jscript.common.parsing.Source; -import me.topchetoeu.jscript.compilation.JavaScript.DeclarationType; -import me.topchetoeu.jscript.compilation.patterns.Pattern; +import me.topchetoeu.jscript.compilation.values.VariableNode; public class VariableDeclareNode extends Node { - public static class Pair { - public final Pattern destructor; - public final Node value; - public final Location location; - - public Pair(Pattern destr, Node value, Location location) { - this.destructor = destr; - this.value = value; - this.location = location; - } - } + @Desugar + public static record Pair(VariableNode var, Node value) { } public final List values; - public final DeclarationType declType; @Override public void resolve(CompileResult target) { - if (!declType.strict) { - for (var entry : values) { - entry.destructor.destructDeclResolve(target); - } - } + for (var entry : values) { + target.scope.define(entry.var.name); + } } @Override public void compile(CompileResult target, boolean pollute) { for (var entry : values) { - if (entry.value == null) { - if (declType == DeclarationType.VAR) entry.destructor.declare(target, null, false); - else entry.destructor.declare(target, declType, false); - } - else { + if (entry.value != null) { entry.value.compile(target, true); - - if (declType == DeclarationType.VAR) entry.destructor.destruct(target, null, true); - else entry.destructor.destruct(target, declType, true); + target.add(VariableNode.toInit(target, loc(), entry.var.name)); } } if (pollute) target.add(Instruction.pushUndefined()); } - public VariableDeclareNode(Location loc, DeclarationType declType, List values) { + public VariableDeclareNode(Location loc, List values) { super(loc); this.values = values; - this.declType = declType; } public static ParseRes parse(Source src, int i) { @@ -70,14 +52,14 @@ public class VariableDeclareNode extends Node { var end = JavaScript.parseStatementEnd(src, i + n); if (end.isSuccess()) { n += end.n; - return ParseRes.res(new VariableDeclareNode(loc, declType.result, res), n); + return ParseRes.res(new VariableDeclareNode(loc, res), n); } while (true) { var nameLoc = src.loc(i + n); - var name = Pattern.parse(src, i + n, false); - if (!name.isSuccess()) return name.chainError(nameLoc, "Expected a variable name or a destructor"); + var name = Parsing.parseIdentifier(src, i + n); + if (!name.isSuccess()) return name.chainError(nameLoc, "Expected a variable name"); n += name.n; Node val = null; @@ -96,7 +78,7 @@ public class VariableDeclareNode extends Node { val = valRes.result; } - res.add(new Pair(name.result, val, nameLoc)); + res.add(new Pair(new VariableNode(nameLoc, name.result), val)); if (src.is(i + n, ",")) { n++; @@ -107,7 +89,7 @@ public class VariableDeclareNode extends Node { if (end.isSuccess()) { n += end.n + endN - n; - return ParseRes.res(new VariableDeclareNode(loc, declType.result, res), n); + return ParseRes.res(new VariableDeclareNode(loc, res), n); } else return end.chainError(src.loc(i + n), "Expected a comma or end of statement"); } diff --git a/src/main/java/me/topchetoeu/jscript/compilation/values/ArgumentsNode.java b/src/main/java/me/topchetoeu/jscript/compilation/values/ArgumentsNode.java index 38ab529..104340f 100644 --- a/src/main/java/me/topchetoeu/jscript/compilation/values/ArgumentsNode.java +++ b/src/main/java/me/topchetoeu/jscript/compilation/values/ArgumentsNode.java @@ -8,7 +8,7 @@ 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)); + if (pollute) target.add(Instruction.loadArgs()); } public ArgumentsNode(Location loc) {