From 5644966dd7c8e9398cecce8e14e7621300546d75 Mon Sep 17 00:00:00 2001 From: TopchetoEU <36534413+TopchetoEU@users.noreply.github.com> Date: Sat, 23 Nov 2024 20:06:04 +0200 Subject: [PATCH] regress: remove ES6 nodes --- .../jscript/compilation/ClassNode.java | 244 ------------------ .../compilation/ClassStatementNode.java | 40 --- .../compilation/FunctionArrowNode.java | 78 ------ .../jscript/compilation/Parameters.java | 84 ------ .../compilation/control/ForOfNode.java | 109 -------- .../members/AssignShorthandNode.java | 57 ---- .../compilation/members/MethodMemberNode.java | 70 ----- .../compilation/patterns/AssignPattern.java | 84 ------ .../jscript/compilation/patterns/Binding.java | 80 ------ .../compilation/patterns/ObjectPattern.java | 161 ------------ .../jscript/compilation/patterns/Pattern.java | 59 ----- .../compilation/values/ClassValueNode.java | 34 --- 12 files changed, 1100 deletions(-) delete mode 100644 src/main/java/me/topchetoeu/jscript/compilation/ClassNode.java delete mode 100644 src/main/java/me/topchetoeu/jscript/compilation/ClassStatementNode.java delete mode 100644 src/main/java/me/topchetoeu/jscript/compilation/FunctionArrowNode.java delete mode 100644 src/main/java/me/topchetoeu/jscript/compilation/Parameters.java delete mode 100644 src/main/java/me/topchetoeu/jscript/compilation/control/ForOfNode.java delete mode 100644 src/main/java/me/topchetoeu/jscript/compilation/members/AssignShorthandNode.java delete mode 100644 src/main/java/me/topchetoeu/jscript/compilation/members/MethodMemberNode.java delete mode 100644 src/main/java/me/topchetoeu/jscript/compilation/patterns/AssignPattern.java delete mode 100644 src/main/java/me/topchetoeu/jscript/compilation/patterns/Binding.java delete mode 100644 src/main/java/me/topchetoeu/jscript/compilation/patterns/ObjectPattern.java delete mode 100644 src/main/java/me/topchetoeu/jscript/compilation/patterns/Pattern.java delete mode 100644 src/main/java/me/topchetoeu/jscript/compilation/values/ClassValueNode.java diff --git a/src/main/java/me/topchetoeu/jscript/compilation/ClassNode.java b/src/main/java/me/topchetoeu/jscript/compilation/ClassNode.java deleted file mode 100644 index 3efad3b..0000000 --- a/src/main/java/me/topchetoeu/jscript/compilation/ClassNode.java +++ /dev/null @@ -1,244 +0,0 @@ -package me.topchetoeu.jscript.compilation; - -import java.util.ArrayList; -import java.util.LinkedList; -import java.util.List; -import java.util.function.Consumer; - -import me.topchetoeu.jscript.common.Instruction; -import me.topchetoeu.jscript.common.SyntaxException; -import me.topchetoeu.jscript.common.Instruction.BreakpointType; -import me.topchetoeu.jscript.common.environment.Environment; -import me.topchetoeu.jscript.common.environment.Key; -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.members.FieldMemberNode; -import me.topchetoeu.jscript.compilation.members.Member; -import me.topchetoeu.jscript.compilation.members.MethodMemberNode; -import me.topchetoeu.jscript.compilation.members.PropertyMemberNode; -import me.topchetoeu.jscript.compilation.scope.FunctionScope; - -public abstract class ClassNode extends FunctionNode { - public static final class ClassBody { - public final List staticMembers; - public final List protoFields; - public final List protoMembers; - public final Parameters constructorParameters; - public final CompoundNode constructorBody; - public final Node superExpr; - public final boolean hasConstr; - - public ClassBody( - List staticMembers, List protoFields, List protoMembers, - Parameters constructorParameters, CompoundNode constructorBody, - Node superExpr, boolean hasConstr - ) { - this.staticMembers = staticMembers; - this.protoFields = protoFields; - this.protoMembers = protoMembers; - this.constructorParameters = constructorParameters; - this.constructorBody = constructorBody; - this.superExpr = superExpr; - this.hasConstr = hasConstr; - } - } - - public static final Key CLASS_ROOT = Key.of(); - public static final Key> SUPER = Key.of(); - public static final Key> SUPER_PROTO = Key.of(); - public static final Key> SUPER_CONSTR = Key.of(); - public static final Key> ON_SUPER_CALL = Key.of(); - - public final ClassBody body; - public final String name; - - @Override public String name() { return name; } - - public void compileStatic(CompileResult target) { - for (var member : body.staticMembers) { - member.compile(target, true, false); - } - } - public void compilePrototype(CompileResult target) { - if (body.protoMembers.size() > 0) { - target.add(Instruction.dup()); - target.add(Instruction.loadMember("prototype")); - - for (var i = 0; i < body.protoMembers.size() - 1; i++) { - body.protoMembers.get(i).compile(target, true, false); - } - - body.protoMembers.get(body.protoMembers.size() - 1).compile(target, false, false); - } - } - - private void compileFieldInits(CompileResult target) { - for (var member : body.protoFields) { - target.add(Instruction.loadThis()); - member.compile(target, false, true); - } - } - - @Override protected void compilePreBody(CompileResult target) { - if (target.env.hasNotNull(SUPER_PROTO)) { - if (!body.hasConstr) { - throw new SyntaxException(loc(), "Default constructors in derived classes not supported"); - // compileFieldInits(target); - } - } - else compileFieldInits(target); - } - - @Override public void compile(CompileResult target, boolean pollute, String name, BreakpointType bp) { - if (body.superExpr == null) { - var id = target.addChild(compileBody(target, name, null)); - target.add(_i -> Instruction.loadFunc(id, false, true, false, false, name, captures(id, target))); - compileStatic(target); - compilePrototype(target); - } - else { - var subtarget = target.subtarget().rootEnvironment(JavaScript.COMPILE_ROOT); - subtarget.scope.singleEntry = true; - subtarget.beginScope(); - var protoVar = target.scope.defineTemp(); - var constrVar = target.scope.defineTemp(); - - subtarget.env.add(SUPER_PROTO, t -> { - var i = t.scope.get(protoVar, false); - t.add(_i -> i.index().toGet()); - }); - subtarget.env.add(SUPER_CONSTR, t -> { - var i = t.scope.get(constrVar, false); - t.add(_i -> i.index().toGet()); - }); - - var staticTarget = subtarget.subEnvironment(); - staticTarget.env.add(SUPER, subtarget.env.get(SUPER_CONSTR)); - staticTarget.env.add(CLASS_ROOT, staticTarget.env); - - var protoTarget = subtarget.subEnvironment(); - protoTarget.env.add(SUPER, subtarget.env.get(SUPER_PROTO)); - protoTarget.env.add(CLASS_ROOT, protoTarget.env); - - var constrEnv = subtarget.env.child(); - constrEnv.add(SUPER, subtarget.env.get(SUPER_PROTO)); - constrEnv.add(ON_SUPER_CALL, this::compileFieldInits); - constrEnv.add(CLASS_ROOT, constrEnv); - - var id = target.addChild(compileBody(constrEnv, new FunctionScope(subtarget.scope), false, name, null)); - target.add(_i -> Instruction.loadFunc(id, false, true, false, true, name, captures(id, target))); - - body.superExpr.compile(target, true); - - target.add(Instruction.extend()); - target.add(Instruction.dup(1, 0)); - target.add(Instruction.loadMember("prototype")); - target.add(_i -> protoVar.index().toInit()); - target.add(_i -> constrVar.index().toInit()); - - compileStatic(staticTarget); - compilePrototype(protoTarget); - subtarget.endScope(); - } - } - - public ClassNode(Location loc, Location end, String name, ClassBody body) { - super(loc, end, body.constructorParameters, body.constructorBody); - - this.name = name; - this.body = body; - } - - public static ParseRes parseMember(Source src, int i) { - return ParseRes.first(src, i, - PropertyMemberNode::parse, - FieldMemberNode::parseClass, - MethodMemberNode::parse - ); - } - - public static ParseRes parseBody(Source src, int i) { - var n = Parsing.skipEmpty(src, i); - var loc = src.loc(i + n); - - ParseRes superExpr = ParseRes.failed(); - - if (Parsing.isIdentifier(src, i + n, "extends")) { - n += 7; - - superExpr = JavaScript.parseExpression(src, i + n, 14); - if (!superExpr.isSuccess()) return superExpr.chainError(src.loc(i + n), "Expected an expression after 'extends'"); - n += superExpr.n; - n += Parsing.skipEmpty(src, i + n); - } - - if (!src.is(i + n, "{")) return ParseRes.error(src.loc(i + n), "Expected a class body"); - n++; - n += Parsing.skipEmpty(src, i + n); - - var fields = new LinkedList(); - var members = new LinkedList(); - var statics = new LinkedList(); - - var params = new Parameters(new ArrayList<>()); - var body = new CompoundNode(loc, false); - var hasConstr = false; - - if (src.is(i + n, "}")) { - n++; - return ParseRes.res(new ClassBody(statics, fields, members, params, body, superExpr.result, false), n); - } - - while (true) { - ParseRes prop = parseMember(src, i + n); - - if (prop.isSuccess()) { - n += prop.n; - - if (prop.result instanceof FieldMemberNode field) fields.add(field); - else if (prop.result instanceof MethodMemberNode method && method.name().equals("constructor")) { - if (hasConstr) return ParseRes.error(loc, "A class may only have one constructor"); - - params = method.params; - body = method.body; - hasConstr = true; - } - else members.add(prop.result); - } - else if (Parsing.isIdentifier(src, i + n, "static")) { - n += 6; - - var staticProp = parseMember(src, i + n); - if (!staticProp.isSuccess()) { - if (prop.isError()) return prop.chainError(); - else return staticProp.chainError(src.loc(i + n), "Expected a member after 'static' keyword"); - } - n += staticProp.n; - - statics.add(staticProp.result); - } - else { - var end = JavaScript.parseStatementEnd(src, i + n); - if (end.isSuccess()) n += end.n; - else return ParseRes.error(src.loc(i + n), "Expected a member, end of statement or a closing colon"); - } - - n += Parsing.skipEmpty(src, i + n); - - if (src.is(i + n, "}")) { - n++; - break; - } - // else return ParseRes.error(src.loc(i + n), "Expected a comma or a closing brace."); - } - - return ParseRes.res(new ClassBody(statics, fields, members, params, body, superExpr.result, hasConstr), n); - } - - // public FunctionStatementNode(Location loc, Location end, Parameters params, CompoundNode body, String name) { - // super(loc, end, params, body); - // this.name = name; - // } -} diff --git a/src/main/java/me/topchetoeu/jscript/compilation/ClassStatementNode.java b/src/main/java/me/topchetoeu/jscript/compilation/ClassStatementNode.java deleted file mode 100644 index eaeb32c..0000000 --- a/src/main/java/me/topchetoeu/jscript/compilation/ClassStatementNode.java +++ /dev/null @@ -1,40 +0,0 @@ -package me.topchetoeu.jscript.compilation; - -import me.topchetoeu.jscript.common.Instruction; -import me.topchetoeu.jscript.common.Instruction.BreakpointType; -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; - -public class ClassStatementNode extends ClassNode { - @Override public void compile(CompileResult target, boolean pollute, String name, BreakpointType bp) { - super.compile(target, pollute, name, bp); - var i = target.scope.define(DeclarationType.LET, name(), loc()); - target.add(_i -> i.index().toInit()); - if (pollute) target.add(Instruction.pushUndefined()); - } - - public ClassStatementNode(Location loc, Location end, String name, ClassBody body) { - super(loc, end, name, body); - } - - public static ParseRes parse(Source src, int i) { - var n = Parsing.skipEmpty(src, i); - var loc = src.loc(i + n); - - if (!Parsing.isIdentifier(src, i + n, "class")) return ParseRes.failed(); - n += 5; - - var name = Parsing.parseIdentifier(src, i + n); - if (!name.isSuccess()) return name.chainError(src.loc(i + n), "Expected a class name"); - n += name.n; - - var body = parseBody(src, i + n); - if (!body.isSuccess()) return body.chainError(src.loc(i + n), "Expected a class body"); - n += body.n; - - return ParseRes.res(new ClassStatementNode(loc, src.loc(i + n), name.result, body.result), n); - } -} diff --git a/src/main/java/me/topchetoeu/jscript/compilation/FunctionArrowNode.java b/src/main/java/me/topchetoeu/jscript/compilation/FunctionArrowNode.java deleted file mode 100644 index d789622..0000000 --- a/src/main/java/me/topchetoeu/jscript/compilation/FunctionArrowNode.java +++ /dev/null @@ -1,78 +0,0 @@ -package me.topchetoeu.jscript.compilation; - -import java.util.Arrays; - -import me.topchetoeu.jscript.common.Instruction; -import me.topchetoeu.jscript.common.Instruction.BreakpointType; -import me.topchetoeu.jscript.common.environment.Environment; -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.control.ReturnNode; -import me.topchetoeu.jscript.compilation.patterns.Pattern; - -public class FunctionArrowNode extends FunctionNode { - @Override public String name() { return null; } - - @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, false, true, false, null, captures(id, target))); - } - - @Override protected Environment rootEnv(Environment env) { - return env.getWith(ClassNode.CLASS_ROOT, () -> super.rootEnv(env)); - } - - public FunctionArrowNode(Location loc, Location end, Parameters params, Node body) { - super(loc, end, params, expToBody(body)); - } - - private static final CompoundNode expToBody(Node node) { - if (node instanceof CompoundNode res) return res; - else return new CompoundNode(node.loc(), false, new ReturnNode(node.loc(), node)); - } - - public static ParseRes parse(Source src, int i) { - var n = Parsing.skipEmpty(src, i); - var loc = src.loc(i + n); - - Parameters params; - - if (src.is(i + n, "(")) { - var paramsRes = Parameters.parseParameters(src, i + n); - if (!paramsRes.isSuccess()) return paramsRes.chainError(); - n += paramsRes.n; - n += Parsing.skipEmpty(src, i + n); - - params = paramsRes.result; - } - else { - var singleParam = Pattern.parse(src, i + n, true); - if (!singleParam.isSuccess()) return ParseRes.failed(); - n += singleParam.n; - n += Parsing.skipEmpty(src, i + n); - - params = new Parameters(Arrays.asList(singleParam.result)); - } - - if (!src.is(i + n, "=>")) return ParseRes.failed(); - n += 2; - n += Parsing.skipEmpty(src, i + 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); - } - 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); - } - } -} diff --git a/src/main/java/me/topchetoeu/jscript/compilation/Parameters.java b/src/main/java/me/topchetoeu/jscript/compilation/Parameters.java deleted file mode 100644 index 712a2e8..0000000 --- a/src/main/java/me/topchetoeu/jscript/compilation/Parameters.java +++ /dev/null @@ -1,84 +0,0 @@ -package me.topchetoeu.jscript.compilation; - -import java.util.ArrayList; -import java.util.List; - -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.patterns.Pattern; -import me.topchetoeu.jscript.compilation.values.operations.AssignNode; - -public final class Parameters { - public final int length; - public final List params; - public final Pattern rest; - - public Parameters(List params, Pattern rest) { - var len = params.size(); - - for (var i = params.size() - 1; i >= 0; i--) { - if (!(params.get(i) instanceof AssignNode)) break; - len--; - } - - this.params = params; - this.length = len; - this.rest = rest; - } - public Parameters(List params) { - this(params, null); - } - - public static ParseRes parseParameters(Source src, int i) { - var n = Parsing.skipEmpty(src, i); - - var openParen = Parsing.parseOperator(src, i + n, "("); - if (!openParen.isSuccess()) return openParen.chainError(src.loc(i + n), "Expected a parameter list"); - n += openParen.n; - - var params = new ArrayList(); - - var closeParen = Parsing.parseOperator(src, i + n, ")"); - n += closeParen.n; - - if (!closeParen.isSuccess()) { - while (true) { - n += Parsing.skipEmpty(src, i + n); - - if (src.is(i + n, "...")) { - n += 3; - - var rest = Pattern.parse(src, i + n, true); - if (!rest.isSuccess()) return ParseRes.error(src.loc(i + n), "Expected a rest parameter"); - n += rest.n; - n += Parsing.skipEmpty(src, i + n); - - if (!src.is(i + n, ")")) return ParseRes.error(src.loc(i + n), "Expected an end of parameters list after rest parameter"); - n++; - - return ParseRes.res(new Parameters(params, rest.result), n); - } - - var param = Pattern.parse(src, i + n, true); - if (!param.isSuccess()) return ParseRes.error(src.loc(i + n), "Expected a parameter or a closing brace"); - n += param.n; - n += Parsing.skipEmpty(src, i + n); - - params.add(param.result); - - if (src.is(i + n, ",")) { - n++; - n += Parsing.skipEmpty(src, i + n); - } - - if (src.is(i + n, ")")) { - n++; - break; - } - } - } - - return ParseRes.res(new Parameters(params), n); - } -} diff --git a/src/main/java/me/topchetoeu/jscript/compilation/control/ForOfNode.java b/src/main/java/me/topchetoeu/jscript/compilation/control/ForOfNode.java deleted file mode 100644 index 9bd3108..0000000 --- a/src/main/java/me/topchetoeu/jscript/compilation/control/ForOfNode.java +++ /dev/null @@ -1,109 +0,0 @@ -package me.topchetoeu.jscript.compilation.control; - -import me.topchetoeu.jscript.common.Instruction; -import me.topchetoeu.jscript.common.Instruction.BreakpointType; -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.CompileResult; -import me.topchetoeu.jscript.compilation.CompoundNode; -import me.topchetoeu.jscript.compilation.DeferredIntSupplier; -import me.topchetoeu.jscript.compilation.JavaScript; -import me.topchetoeu.jscript.compilation.LabelContext; -import me.topchetoeu.jscript.compilation.Node; -import me.topchetoeu.jscript.compilation.patterns.Binding; - -public class ForOfNode extends Node { - public final Binding binding; - public final Node iterable, body; - public final String label; - - @Override public void resolve(CompileResult target) { - body.resolve(target); - binding.resolve(target); - } - - @Override public void compile(CompileResult target, boolean pollute) { - binding.declareLateInit(target); - - iterable.compile(target, true, BreakpointType.STEP_OVER); - target.add(Instruction.dup()); - target.add(Instruction.loadIntrinsics("it_key")); - target.add(Instruction.loadMember()).setLocation(iterable.loc()); - target.add(Instruction.call(0, true)).setLocation(iterable.loc()); - - int start = target.size(); - target.add(Instruction.dup(2, 0)); - target.add(Instruction.loadMember("next")).setLocation(iterable.loc()); - target.add(Instruction.call(0, true)).setLocation(iterable.loc()); - target.add(Instruction.dup()); - target.add(Instruction.loadMember("done")).setLocation(iterable.loc()); - int mid = target.temp(); - - target.add(Instruction.loadMember("value")).setLocation(binding.loc); - binding.assign(target, false); - - var end = new DeferredIntSupplier(); - - LabelContext.pushLoop(target.env, loc(), label, end, start); - CompoundNode.compileMultiEntry(body, target, false, BreakpointType.STEP_OVER); - LabelContext.popLoop(target.env, label); - - int endI = target.size(); - end.set(endI); - - target.add(Instruction.jmp(start - endI)); - target.add(Instruction.discard()); - target.add(Instruction.discard()); - target.set(mid, Instruction.jmpIf(endI - mid + 1)); - if (pollute) target.add(Instruction.pushUndefined()); - } - - public ForOfNode(Location loc, String label, Binding binding, Node object, Node body) { - super(loc); - this.label = label; - this.binding = binding; - this.iterable = object; - this.body = body; - } - - public static ParseRes parse(Source src, int i) { - var n = Parsing.skipEmpty(src, i); - var loc = src.loc(i + n); - - var label = JavaScript.parseLabel(src, i + n); - n += label.n; - n += Parsing.skipEmpty(src, i + n); - - if (!Parsing.isIdentifier(src, i + n, "for")) return ParseRes.failed(); - n += 3; - n += Parsing.skipEmpty(src, i + n); - - if (!src.is(i + n, "(")) return ParseRes.error(src.loc(i + n), "Expected an opening paren"); - n++; - n += Parsing.skipEmpty(src, i + n); - - var binding = Binding.parse(src, i + n); - if (!binding.isSuccess()) return ParseRes.error(src.loc(i + n), "Expected a binding in for-of loop"); - n += binding.n; - n += Parsing.skipEmpty(src, i + n); - - if (!Parsing.isIdentifier(src, i + n, "of")) return ParseRes.error(src.loc(i + n), "Expected 'of' keyword after variable declaration"); - n += 2; - - var obj = JavaScript.parseExpression(src, i + n, 0); - if (!obj.isSuccess()) return obj.chainError(src.loc(i + n), "Expected a value"); - n += obj.n; - n += Parsing.skipEmpty(src, i + n); - - if (!src.is(i + n, ")")) return ParseRes.error(src.loc(i + n), "Expected a closing paren"); - n++; - - var bodyRes = JavaScript.parseStatement(src, i + n); - if (!bodyRes.isSuccess()) return bodyRes.chainError(src.loc(i + n), "Expected a for-of body"); - n += bodyRes.n; - - return ParseRes.res(new ForOfNode(loc, label.result, binding.result, obj.result, bodyRes.result), n); - } -} diff --git a/src/main/java/me/topchetoeu/jscript/compilation/members/AssignShorthandNode.java b/src/main/java/me/topchetoeu/jscript/compilation/members/AssignShorthandNode.java deleted file mode 100644 index 116f787..0000000 --- a/src/main/java/me/topchetoeu/jscript/compilation/members/AssignShorthandNode.java +++ /dev/null @@ -1,57 +0,0 @@ -package me.topchetoeu.jscript.compilation.members; - -import me.topchetoeu.jscript.common.SyntaxException; -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.CompileResult; -import me.topchetoeu.jscript.compilation.JavaScript; -import me.topchetoeu.jscript.compilation.Node; -import me.topchetoeu.jscript.compilation.patterns.AssignTarget; -import me.topchetoeu.jscript.compilation.values.VariableNode; -import me.topchetoeu.jscript.compilation.values.constants.StringNode; -import me.topchetoeu.jscript.compilation.values.operations.AssignNode; - -public class AssignShorthandNode implements Member { - public final Location loc; - public final Node key; - public final AssignTarget target; - public final Node value; - - @Override public Location loc() { return loc; } - - @Override public void compile(CompileResult target, boolean pollute, boolean enumerable) { - throw new SyntaxException(loc(), "Unexpected assign shorthand in non-destructor context"); - } - - public AssignShorthandNode(Location loc, Node key, AssignTarget target, Node value) { - this.loc = loc; - this.key = key; - this.target = target; - this.value = value; - } - - public AssignTarget target() { - return new AssignNode(loc(), target, value); - } - - public static ParseRes parse(Source src, int i) { - var n = Parsing.skipEmpty(src, i); - var loc = src.loc(i + n); - - var var = VariableNode.parse(src, i + n); - if (!var.isSuccess()) return var.chainError(); - n += var.n; - n += Parsing.skipEmpty(src, i + n); - - if (!src.is(i + n, "=")) return ParseRes.failed(); - n++; - - var value = JavaScript.parseExpression(src, i + n, 2); - if (!value.isSuccess()) return value.chainError(src.loc(i + n), "Expected a shorthand initializer"); - n += value.n; - - return ParseRes.res(new AssignShorthandNode(loc, new StringNode(loc, var.result.name), var.result, value.result), n); - } -} \ No newline at end of file diff --git a/src/main/java/me/topchetoeu/jscript/compilation/members/MethodMemberNode.java b/src/main/java/me/topchetoeu/jscript/compilation/members/MethodMemberNode.java deleted file mode 100644 index abc760e..0000000 --- a/src/main/java/me/topchetoeu/jscript/compilation/members/MethodMemberNode.java +++ /dev/null @@ -1,70 +0,0 @@ -package me.topchetoeu.jscript.compilation.members; - -import me.topchetoeu.jscript.common.Instruction; -import me.topchetoeu.jscript.common.Instruction.BreakpointType; -import me.topchetoeu.jscript.common.environment.Environment; -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.CompileResult; -import me.topchetoeu.jscript.compilation.CompoundNode; -import me.topchetoeu.jscript.compilation.FunctionNode; -import me.topchetoeu.jscript.compilation.Node; -import me.topchetoeu.jscript.compilation.Parameters; -import me.topchetoeu.jscript.compilation.values.ObjectNode; -import me.topchetoeu.jscript.compilation.values.constants.StringNode; - -public class MethodMemberNode extends FunctionNode implements Member { - public final Node key; - - @Override public String name() { - if (key instanceof StringNode str) return str.value; - else return null; - } - - @Override protected Environment rootEnv(Environment env) { - return env; - } - - @Override public void compile(CompileResult target, boolean pollute, String name, BreakpointType bp) { - if (pollute) target.add(Instruction.dup()); - key.compile(target, true); - - var id = target.addChild(compileBody(target, name, null)); - target.add(_i -> Instruction.loadFunc(id, true, false, false, false, null, captures(id, target))); - } - - @Override public void compile(CompileResult target, boolean pollute, boolean enumerable) { - compile(target, pollute); - target.add(Instruction.defField(enumerable)); - } - - public MethodMemberNode(Location loc, Location end, Node key, Parameters params, CompoundNode body) { - super(loc, end, params, body); - this.key = key; - } - - public static ParseRes parse(Source src, int i) { - var n = Parsing.skipEmpty(src, i); - var loc = src.loc(i + n); - - var name = ObjectNode.parsePropName(src, i + n); - if (!name.isSuccess()) return name.chainError(); - n += name.n; - - var params = Parameters.parseParameters(src, i + n); - if (!params.isSuccess()) return params.chainError(src.loc(i + n), "Expected an argument list"); - n += params.n; - - var body = CompoundNode.parse(src, i + n); - if (!body.isSuccess()) return body.chainError(src.loc(i + n), "Expected a compound statement for property accessor."); - n += body.n; - - var end = src.loc(i + n - 1); - - return ParseRes.res(new MethodMemberNode( - loc, end, name.result, params.result, body.result - ), n); - } -} \ No newline at end of file diff --git a/src/main/java/me/topchetoeu/jscript/compilation/patterns/AssignPattern.java b/src/main/java/me/topchetoeu/jscript/compilation/patterns/AssignPattern.java deleted file mode 100644 index e6ea21a..0000000 --- a/src/main/java/me/topchetoeu/jscript/compilation/patterns/AssignPattern.java +++ /dev/null @@ -1,84 +0,0 @@ -package me.topchetoeu.jscript.compilation.patterns; - -import me.topchetoeu.jscript.common.Instruction; -import me.topchetoeu.jscript.common.Operation; -import me.topchetoeu.jscript.common.SyntaxException; -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.CompileResult; -import me.topchetoeu.jscript.compilation.JavaScript; -import me.topchetoeu.jscript.compilation.Node; -import me.topchetoeu.jscript.compilation.JavaScript.DeclarationType; - -public class AssignPattern implements Pattern { - public final Location loc; - public final AssignTarget assignable; - public final Node value; - - @Override public Location loc() { return loc; } - - @Override public void destructDeclResolve(CompileResult target) { - if (!(assignable instanceof Pattern p)) throw new SyntaxException(assignable.loc(), "Unexpected non-pattern in destruct context"); - p.destructDeclResolve(target); - } - - private void common(CompileResult target) { - target.add(Instruction.dup()); - target.add(Instruction.pushUndefined()); - target.add(Instruction.operation(Operation.EQUALS)); - var start = target.temp(); - target.add(Instruction.discard()); - - value.compile(target, true); - - target.set(start, Instruction.jmpIfNot(target.size() - start)); - } - - @Override public void declare(CompileResult target, DeclarationType decl, boolean lateInitializer) { - if (lateInitializer) { - if (assignable instanceof Pattern p) p.declare(target, decl, lateInitializer); - else throw new SyntaxException(assignable.loc(), "Unexpected non-pattern in destruct context"); - } - else throw new SyntaxException(loc(), "Expected an assignment value for destructor declaration"); - } - @Override public void destruct(CompileResult target, DeclarationType decl, boolean shouldDeclare) { - if (!(assignable instanceof Pattern p)) throw new SyntaxException(assignable.loc(), "Unexpected non-pattern in destruct context"); - common(target); - p.destruct(target, decl, shouldDeclare); - } - - @Override public void beforeAssign(CompileResult target) { - assignable.beforeAssign(target); - } - @Override public void afterAssign(CompileResult target, boolean pollute) { - common(target); - assignable.afterAssign(target, false); - } - - public AssignPattern(Location loc, Pattern assignable, Node value) { - this.loc = loc; - this.assignable = assignable; - this.value = value; - } - - public static ParseRes parse(Source src, int i) { - var n = Parsing.skipEmpty(src, i); - var loc = src.loc(i + n); - - var pattern = Pattern.parse(src, i + n, false); - if (!pattern.isSuccess()) return pattern.chainError(); - n += pattern.n; - n += Parsing.skipEmpty(src, i + n); - - if (!src.is(i + n, "=")) return ParseRes.failed(); - n++; - - var value = JavaScript.parseExpression(src, i + n, 2); - if (!value.isSuccess()) return value.chainError(src.loc(i + n), "Expected a default value"); - n += value.n; - - return ParseRes.res(new AssignPattern(loc, pattern.result, value.result), n); - } -} diff --git a/src/main/java/me/topchetoeu/jscript/compilation/patterns/Binding.java b/src/main/java/me/topchetoeu/jscript/compilation/patterns/Binding.java deleted file mode 100644 index bf7524f..0000000 --- a/src/main/java/me/topchetoeu/jscript/compilation/patterns/Binding.java +++ /dev/null @@ -1,80 +0,0 @@ -package me.topchetoeu.jscript.compilation.patterns; - -import me.topchetoeu.jscript.common.SyntaxException; -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.CompileResult; -import me.topchetoeu.jscript.compilation.JavaScript; -import me.topchetoeu.jscript.compilation.JavaScript.DeclarationType; - -public class Binding implements Pattern { - public final Location loc; - public final DeclarationType type; - public final AssignTarget assignable; - - @Override public Location loc() { return loc; } - - @Override public void destructDeclResolve(CompileResult target) { - if (type != null && !type.strict) { - if (!(assignable instanceof Pattern p)) throw new SyntaxException(assignable.loc(), "Unexpected non-pattern in destruct context"); - p.destructDeclResolve(target); - } - } - - @Override public void destruct(CompileResult target, DeclarationType decl, boolean shouldDeclare) { - if (!(assignable instanceof Pattern p)) throw new SyntaxException(assignable.loc(), "Unexpected non-pattern in destruct context"); - p.destruct(target, decl, shouldDeclare); - } - @Override public void declare(CompileResult target, DeclarationType decl, boolean lateInitializer) { - if (!(assignable instanceof Pattern p)) throw new SyntaxException(assignable.loc(), "Unexpected non-pattern in destruct context"); - p.declare(target, decl, lateInitializer); - } - - public void resolve(CompileResult target) { - if (type != null) destructDeclResolve(target); - } - - public void declare(CompileResult target, boolean hasInit) { - if (type != null) destructVar(target, type, hasInit); - } - public void declareLateInit(CompileResult target) { - if (type != null) declare(target, type, true); - } - - @Override public void afterAssign(CompileResult target, boolean pollute) { - assignable.assign(target, pollute); - } - - public Binding(Location loc, DeclarationType type, AssignTarget assignable) { - this.loc = loc; - this.type = type; - this.assignable = assignable; - } - - public static ParseRes parse(Source src, int i) { - var n = Parsing.skipEmpty(src, i); - var loc = src.loc(i + n); - - var declType = JavaScript.parseDeclarationType(src, i + n); - if (!declType.isSuccess()) { - var res = JavaScript.parseExpression(src, i + n, 13); - if (res.isSuccess() && res.result instanceof AssignTargetLike target) { - n += res.n; - return ParseRes.res(new Binding(loc, null, target.toAssignTarget()), n); - } - else return ParseRes.failed(); - } - else { - n += declType.n; - n += Parsing.skipEmpty(src, i + n); - - var res = Pattern.parse(src, i + n, false); - if (!res.isSuccess()) return ParseRes.failed(); - n += res.n; - - return ParseRes.res(new Binding(loc, declType.result, res.result), n); - } - } -} diff --git a/src/main/java/me/topchetoeu/jscript/compilation/patterns/ObjectPattern.java b/src/main/java/me/topchetoeu/jscript/compilation/patterns/ObjectPattern.java deleted file mode 100644 index 65e508d..0000000 --- a/src/main/java/me/topchetoeu/jscript/compilation/patterns/ObjectPattern.java +++ /dev/null @@ -1,161 +0,0 @@ -package me.topchetoeu.jscript.compilation.patterns; - -import java.util.LinkedList; -import java.util.List; -import java.util.function.Consumer; - -import me.topchetoeu.jscript.common.Instruction; -import me.topchetoeu.jscript.common.SyntaxException; -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.CompileResult; -import me.topchetoeu.jscript.compilation.Node; -import me.topchetoeu.jscript.compilation.JavaScript.DeclarationType; -import me.topchetoeu.jscript.compilation.values.ObjectNode; -import me.topchetoeu.jscript.compilation.values.VariableNode; -import me.topchetoeu.jscript.compilation.values.constants.StringNode; -import me.topchetoeu.jscript.compilation.values.operations.IndexNode; - -public class ObjectPattern extends Node implements Pattern { - public static final class Member { - public final Node key; - public final AssignTarget consumable; - - public Member(Node key, AssignTarget consumer) { - this.key = key; - this.consumable = consumer; - } - } - - public final List members; - - public void compile(CompileResult target, Consumer consumer, boolean pollute) { - for (var el : members) { - target.add(Instruction.dup()); - IndexNode.indexLoad(target, el.key, true); - consumer.accept(el.consumable); - } - - if (!pollute) target.add(Instruction.discard()); - } - - @Override public void destructDeclResolve(CompileResult target) { - for (var t : members) { - if (t.consumable instanceof Pattern p) p.destructDeclResolve(target); - else throw new SyntaxException(t.consumable.loc(), "Unexpected non-pattern in destruct context"); - } - } - - @Override public void destruct(CompileResult target, DeclarationType decl, boolean shouldDeclare) { - compile(target, t -> { - if (t instanceof Pattern p) p.destruct(target, decl, shouldDeclare); - else throw new SyntaxException(t.loc(), "Unexpected non-pattern in destruct context"); - }, false); - } - - @Override public void afterAssign(CompileResult target, boolean pollute) { - compile(target, t -> t.assign(target, false), pollute); - } - - @Override public void declare(CompileResult target, DeclarationType decl, boolean lateInitializer) { - if (lateInitializer) { - for (var t : members) { - if (t.consumable instanceof Pattern p) p.declare(target, decl, lateInitializer); - else throw new SyntaxException(t.consumable.loc(), "Unexpected non-pattern in destruct context"); - } - } - else throw new SyntaxException(loc(), "Object pattern must be initialized"); - } - - public ObjectPattern(Location loc, List members) { - super(loc); - this.members = members; - } - - private static ParseRes parseShorthand(Source src, int i) { - ParseRes res = ParseRes.first(src, i, - AssignPattern::parse, - VariableNode::parse - ); - - if (res.isSuccess()) { - if (res.result instanceof AssignPattern assign) { - if (assign.assignable instanceof VariableNode var) { - return ParseRes.res(new Member(new StringNode(var.loc(), var.name), res.result), res.n); - } - } - else if (res.result instanceof VariableNode var) { - return ParseRes.res(new Member(new StringNode(var.loc(), var.name), res.result), res.n); - } - } - - return res.chainError(); - } - private static ParseRes parseKeyed(Source src, int i) { - var n = Parsing.skipEmpty(src, i); - - var key = ObjectNode.parsePropName(src, i + n); - if (!key.isSuccess()) return key.chainError(); - n += key.n; - n += Parsing.skipEmpty(src, i + n); - - if (!src.is(i + n , ":")) return ParseRes.failed(); - n++; - - ParseRes res = Pattern.parse(src, i + n, true); - if (!res.isSuccess()) return ParseRes.error(src.loc(i + n), "Expected a pattern after colon"); - n += res.n; - - return ParseRes.res(new Member(key.result, res.result), n); - } - - public static ParseRes parse(Source src, int i) { - var n = Parsing.skipEmpty(src, i); - var loc = src.loc(i + n); - - if (!src.is(i + n, "{")) return ParseRes.failed(); - n++; - n += Parsing.skipEmpty(src, i + n); - - var members = new LinkedList(); - - if (src.is(i + n, "}")) { - n++; - return ParseRes.res(new ObjectPattern(loc, members), n); - } - - while (true) { - ParseRes prop = ParseRes.first(src, i + n, - ObjectPattern::parseKeyed, - ObjectPattern::parseShorthand - ); - - if (!prop.isSuccess()) return prop.chainError(src.loc(i + n), "Expected a member in object pattern"); - n += prop.n; - - members.add(prop.result); - - n += Parsing.skipEmpty(src, i + n); - if (src.is(i + n, ",")) { - n++; - n += Parsing.skipEmpty(src, i + n); - - if (src.is(i + n, "}")) { - n++; - break; - } - - continue; - } - else if (src.is(i + n, "}")) { - n++; - break; - } - else ParseRes.error(src.loc(i + n), "Expected a comma or a closing brace."); - } - - return ParseRes.res(new ObjectPattern(loc, members), n); - } -} diff --git a/src/main/java/me/topchetoeu/jscript/compilation/patterns/Pattern.java b/src/main/java/me/topchetoeu/jscript/compilation/patterns/Pattern.java deleted file mode 100644 index 07d07fb..0000000 --- a/src/main/java/me/topchetoeu/jscript/compilation/patterns/Pattern.java +++ /dev/null @@ -1,59 +0,0 @@ -package me.topchetoeu.jscript.compilation.patterns; - -import me.topchetoeu.jscript.common.parsing.Location; -import me.topchetoeu.jscript.common.parsing.ParseRes; -import me.topchetoeu.jscript.common.parsing.Source; -import me.topchetoeu.jscript.compilation.CompileResult; -import me.topchetoeu.jscript.compilation.JavaScript.DeclarationType; -import me.topchetoeu.jscript.compilation.values.VariableNode; - -/** - * Represents all nodes that can be a destructors (note that all destructors are assign targets, too) - */ -public interface Pattern extends AssignTarget { - Location loc(); - - /** - * Called when the destructor has to declare - * @param target - */ - void destructDeclResolve(CompileResult target); - - /** - * Called when a declaration-like is being destructed - * @param decl The variable type the destructor must declare, if it is a named pne - */ - void destruct(CompileResult target, DeclarationType decl, boolean shouldDeclare); - - /** - * Run when destructing a declaration without an initializer - */ - void declare(CompileResult target, DeclarationType decl, boolean lateInitializer); - - public default void destructArg(CompileResult target, DeclarationType decl) { - destruct(target, decl, false); - } - public default void destructVar(CompileResult target, DeclarationType decl, boolean hasInitializer) { - if (hasInitializer) { - if (decl == null || !decl.strict) destruct(target, null, true); - else destruct(target, decl, true); - } - else { - if (decl == null || !decl.strict) declare(target, null, false); - else declare(target, decl, false); - } - } - - public static ParseRes parse(Source src, int i, boolean withDefault) { - return withDefault ? - ParseRes.first(src, i, - AssignPattern::parse, - ObjectPattern::parse, - VariableNode::parse - ) : - ParseRes.first(src, i, - ObjectPattern::parse, - VariableNode::parse - ); - } -} diff --git a/src/main/java/me/topchetoeu/jscript/compilation/values/ClassValueNode.java b/src/main/java/me/topchetoeu/jscript/compilation/values/ClassValueNode.java deleted file mode 100644 index e0240f4..0000000 --- a/src/main/java/me/topchetoeu/jscript/compilation/values/ClassValueNode.java +++ /dev/null @@ -1,34 +0,0 @@ -package me.topchetoeu.jscript.compilation.values; - -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.ClassNode; -import me.topchetoeu.jscript.compilation.JavaScript; - -public class ClassValueNode extends ClassNode { - public ClassValueNode(Location loc, Location end, String name, ClassBody body) { - super(loc, end, name, body); - } - - public static ParseRes parse(Source src, int i) { - var n = Parsing.skipEmpty(src, i); - var loc = src.loc(i + n); - - if (!Parsing.isIdentifier(src, i + n, "class")) return ParseRes.failed(); - n += 5; - - var name = Parsing.parseIdentifier(src, i + n); - if (name.isSuccess() && !JavaScript.checkVarName(name.result)) { - name = ParseRes.error(src.loc(i + n), "Unexpected keyword '" + name.result + "'"); - } - n += name.n; - - var body = parseBody(src, i + n); - if (!body.isSuccess()) return body.chainError(name).chainError(src.loc(i + n), "Expected a class body"); - n += body.n; - - return ParseRes.res(new ClassValueNode(loc, src.loc(i + n), name.result, body.result), n); - } -}