refactor: rename statements to nodes
This commit is contained in:
parent
a45f4109d8
commit
89ba921b4a
@ -1,6 +1,6 @@
|
||||
package me.topchetoeu.jscript.common.parsing;
|
||||
|
||||
import me.topchetoeu.jscript.compilation.values.constants.NumberStatement;
|
||||
import me.topchetoeu.jscript.compilation.values.constants.NumberNode;
|
||||
import me.topchetoeu.jscript.runtime.exceptions.SyntaxException;
|
||||
|
||||
public class Parsing {
|
||||
@ -276,8 +276,8 @@ public class Parsing {
|
||||
if (negative) return ParseRes.error(src.loc(i + n), "Expected number immediatly after minus");
|
||||
return ParseRes.failed();
|
||||
}
|
||||
else if (negative) return ParseRes.res(-(whole + fract) * NumberStatement.power(10, exponent), n);
|
||||
else return ParseRes.res((whole + fract) * NumberStatement.power(10, exponent), n);
|
||||
else if (negative) return ParseRes.res(-(whole + fract) * NumberNode.power(10, exponent), n);
|
||||
else return ParseRes.res((whole + fract) * NumberNode.power(10, exponent), n);
|
||||
}
|
||||
public static ParseRes<Double> parseFloat(Source src, int i, boolean withMinus) {
|
||||
var n = skipEmpty(src, i);
|
||||
@ -336,8 +336,8 @@ public class Parsing {
|
||||
if (negative) return ParseRes.error(src.loc(i + n), "Expected number immediatly after minus");
|
||||
return ParseRes.failed();
|
||||
}
|
||||
else if (negative) return ParseRes.res(-(whole + fract) * NumberStatement.power(10, exponent), n);
|
||||
else return ParseRes.res((whole + fract) * NumberStatement.power(10, exponent), n);
|
||||
else if (negative) return ParseRes.res(-(whole + fract) * NumberNode.power(10, exponent), n);
|
||||
else return ParseRes.res((whole + fract) * NumberNode.power(10, exponent), n);
|
||||
}
|
||||
public static ParseRes<Double> parseInt(Source src, int i, String alphabet, boolean withMinus) {
|
||||
var n = skipEmpty(src, i);
|
||||
|
@ -0,0 +1,7 @@
|
||||
package me.topchetoeu.jscript.compilation;
|
||||
|
||||
import me.topchetoeu.jscript.common.Operation;
|
||||
|
||||
public interface AssignableNode {
|
||||
public abstract Node toAssign(Node val, Operation operation);
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
package me.topchetoeu.jscript.compilation;
|
||||
|
||||
import me.topchetoeu.jscript.common.Operation;
|
||||
|
||||
public interface AssignableStatement {
|
||||
public abstract Statement toAssign(Statement val, Operation operation);
|
||||
}
|
@ -10,10 +10,10 @@ 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.values.FunctionStatement;
|
||||
import me.topchetoeu.jscript.compilation.values.FunctionNode;
|
||||
|
||||
public class CompoundStatement extends Statement {
|
||||
public final Statement[] statements;
|
||||
public class CompoundNode extends Node {
|
||||
public final Node[] statements;
|
||||
public final boolean separateFuncs;
|
||||
public Location end;
|
||||
|
||||
@ -32,9 +32,9 @@ public class CompoundStatement extends Statement {
|
||||
|
||||
@Override
|
||||
public void compile(CompileResult target, boolean pollute, BreakpointType type) {
|
||||
List<Statement> statements = new Vector<Statement>();
|
||||
List<Node> statements = new Vector<Node>();
|
||||
if (separateFuncs) for (var stm : this.statements) {
|
||||
if (stm instanceof FunctionStatement && ((FunctionStatement)stm).statement) {
|
||||
if (stm instanceof FunctionNode && ((FunctionNode)stm).statement) {
|
||||
stm.compile(target, false);
|
||||
}
|
||||
else statements.add(stm);
|
||||
@ -55,18 +55,18 @@ public class CompoundStatement extends Statement {
|
||||
}
|
||||
}
|
||||
|
||||
public CompoundStatement setEnd(Location loc) {
|
||||
public CompoundNode setEnd(Location loc) {
|
||||
this.end = loc;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CompoundStatement(Location loc, boolean separateFuncs, Statement ...statements) {
|
||||
public CompoundNode(Location loc, boolean separateFuncs, Node ...statements) {
|
||||
super(loc);
|
||||
this.separateFuncs = separateFuncs;
|
||||
this.statements = statements;
|
||||
}
|
||||
|
||||
public static ParseRes<CompoundStatement> parseComma(Source src, int i, Statement prev, int precedence) {
|
||||
public static ParseRes<CompoundNode> parseComma(Source src, int i, Node prev, int precedence) {
|
||||
if (precedence > 1) return ParseRes.failed();
|
||||
|
||||
var n = Parsing.skipEmpty(src, i);
|
||||
@ -79,16 +79,16 @@ public class CompoundStatement extends Statement {
|
||||
if (!res.isSuccess()) return res.chainError(src.loc(i + n), "Expected a value after the comma");
|
||||
n += res.n;
|
||||
|
||||
return ParseRes.res(new CompoundStatement(loc, false, prev, res.result), n);
|
||||
return ParseRes.res(new CompoundNode(loc, false, prev, res.result), n);
|
||||
}
|
||||
public static ParseRes<CompoundStatement> parse(Source src, int i) {
|
||||
public static ParseRes<CompoundNode> 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++;
|
||||
|
||||
var statements = new ArrayList<Statement>();
|
||||
var statements = new ArrayList<Node>();
|
||||
|
||||
while (true) {
|
||||
n += Parsing.skipEmpty(src, i + n);
|
||||
@ -109,6 +109,6 @@ public class CompoundStatement extends Statement {
|
||||
statements.add(res.result);
|
||||
}
|
||||
|
||||
return ParseRes.res(new CompoundStatement(loc, true, statements.toArray(Statement[]::new)).setEnd(src.loc(i + n - 1)), n);
|
||||
return ParseRes.res(new CompoundNode(loc, true, statements.toArray(Node[]::new)).setEnd(src.loc(i + n - 1)), n);
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
package me.topchetoeu.jscript.compilation;
|
||||
|
||||
public class ExpressionParser {
|
||||
public class ExpressionNode {
|
||||
|
||||
}
|
@ -10,38 +10,38 @@ import me.topchetoeu.jscript.common.parsing.Filename;
|
||||
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.BreakStatement;
|
||||
import me.topchetoeu.jscript.compilation.control.ContinueStatement;
|
||||
import me.topchetoeu.jscript.compilation.control.DebugStatement;
|
||||
import me.topchetoeu.jscript.compilation.control.DeleteStatement;
|
||||
import me.topchetoeu.jscript.compilation.control.DoWhileStatement;
|
||||
import me.topchetoeu.jscript.compilation.control.ForInStatement;
|
||||
import me.topchetoeu.jscript.compilation.control.ForOfStatement;
|
||||
import me.topchetoeu.jscript.compilation.control.ForStatement;
|
||||
import me.topchetoeu.jscript.compilation.control.IfStatement;
|
||||
import me.topchetoeu.jscript.compilation.control.ReturnStatement;
|
||||
import me.topchetoeu.jscript.compilation.control.SwitchStatement;
|
||||
import me.topchetoeu.jscript.compilation.control.ThrowStatement;
|
||||
import me.topchetoeu.jscript.compilation.control.TryStatement;
|
||||
import me.topchetoeu.jscript.compilation.control.WhileStatement;
|
||||
import me.topchetoeu.jscript.compilation.control.BreakNode;
|
||||
import me.topchetoeu.jscript.compilation.control.ContinueNode;
|
||||
import me.topchetoeu.jscript.compilation.control.DebugNode;
|
||||
import me.topchetoeu.jscript.compilation.control.DeleteNode;
|
||||
import me.topchetoeu.jscript.compilation.control.DoWhileNode;
|
||||
import me.topchetoeu.jscript.compilation.control.ForInNode;
|
||||
import me.topchetoeu.jscript.compilation.control.ForOfNode;
|
||||
import me.topchetoeu.jscript.compilation.control.ForNode;
|
||||
import me.topchetoeu.jscript.compilation.control.IfNode;
|
||||
import me.topchetoeu.jscript.compilation.control.ReturnNode;
|
||||
import me.topchetoeu.jscript.compilation.control.SwitchNode;
|
||||
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.LocalScopeRecord;
|
||||
import me.topchetoeu.jscript.compilation.values.ArrayStatement;
|
||||
import me.topchetoeu.jscript.compilation.values.FunctionStatement;
|
||||
import me.topchetoeu.jscript.compilation.values.GlobalThisStatement;
|
||||
import me.topchetoeu.jscript.compilation.values.ObjectStatement;
|
||||
import me.topchetoeu.jscript.compilation.values.RegexStatement;
|
||||
import me.topchetoeu.jscript.compilation.values.VariableStatement;
|
||||
import me.topchetoeu.jscript.compilation.values.constants.BoolStatement;
|
||||
import me.topchetoeu.jscript.compilation.values.constants.NullStatement;
|
||||
import me.topchetoeu.jscript.compilation.values.constants.NumberStatement;
|
||||
import me.topchetoeu.jscript.compilation.values.constants.StringStatement;
|
||||
import me.topchetoeu.jscript.compilation.values.operations.CallStatement;
|
||||
import me.topchetoeu.jscript.compilation.values.operations.ChangeStatement;
|
||||
import me.topchetoeu.jscript.compilation.values.operations.DiscardStatement;
|
||||
import me.topchetoeu.jscript.compilation.values.operations.IndexStatement;
|
||||
import me.topchetoeu.jscript.compilation.values.operations.OperationStatement;
|
||||
import me.topchetoeu.jscript.compilation.values.operations.TypeofStatement;
|
||||
import me.topchetoeu.jscript.compilation.values.operations.VariableIndexStatement;
|
||||
import me.topchetoeu.jscript.compilation.values.ArrayNode;
|
||||
import me.topchetoeu.jscript.compilation.values.FunctionNode;
|
||||
import me.topchetoeu.jscript.compilation.values.GlobalThisNode;
|
||||
import me.topchetoeu.jscript.compilation.values.ObjectNode;
|
||||
import me.topchetoeu.jscript.compilation.values.RegexNode;
|
||||
import me.topchetoeu.jscript.compilation.values.VariableNode;
|
||||
import me.topchetoeu.jscript.compilation.values.constants.BoolNode;
|
||||
import me.topchetoeu.jscript.compilation.values.constants.NullNode;
|
||||
import me.topchetoeu.jscript.compilation.values.constants.NumberNode;
|
||||
import me.topchetoeu.jscript.compilation.values.constants.StringNode;
|
||||
import me.topchetoeu.jscript.compilation.values.operations.CallNode;
|
||||
import me.topchetoeu.jscript.compilation.values.operations.ChangeNode;
|
||||
import me.topchetoeu.jscript.compilation.values.operations.DiscardNode;
|
||||
import me.topchetoeu.jscript.compilation.values.operations.IndexNode;
|
||||
import me.topchetoeu.jscript.compilation.values.operations.OperationNode;
|
||||
import me.topchetoeu.jscript.compilation.values.operations.TypeofNode;
|
||||
import me.topchetoeu.jscript.compilation.values.operations.VariableIndexNode;
|
||||
import me.topchetoeu.jscript.runtime.exceptions.SyntaxException;
|
||||
|
||||
public class JavaScript {
|
||||
@ -53,7 +53,7 @@ public class JavaScript {
|
||||
"protected", "public", "static"
|
||||
);
|
||||
|
||||
public static ParseRes<? extends Statement> parseParens(Source src, int i) {
|
||||
public static ParseRes<? extends Node> parseParens(Source src, int i) {
|
||||
int n = 0;
|
||||
|
||||
var openParen = Parsing.parseOperator(src, i + n, "(");
|
||||
@ -71,28 +71,28 @@ public class JavaScript {
|
||||
return ParseRes.res(res.result, n);
|
||||
}
|
||||
|
||||
public static ParseRes<? extends Statement> parseSimple(Source src, int i, boolean statement) {
|
||||
public static ParseRes<? extends Node> parseSimple(Source src, int i, boolean statement) {
|
||||
return ParseRes.first(src, i,
|
||||
(s, j) -> statement ? ParseRes.failed() : ObjectStatement.parse(s, j),
|
||||
(s, j) -> statement ? ParseRes.failed() : FunctionStatement.parseFunction(s, j, false),
|
||||
(s, j) -> statement ? ParseRes.failed() : ObjectNode.parse(s, j),
|
||||
(s, j) -> statement ? ParseRes.failed() : FunctionNode.parseFunction(s, j, false),
|
||||
JavaScript::parseLiteral,
|
||||
StringStatement::parse,
|
||||
RegexStatement::parse,
|
||||
NumberStatement::parse,
|
||||
ChangeStatement::parsePrefixDecrease,
|
||||
ChangeStatement::parsePrefixIncrease,
|
||||
OperationStatement::parsePrefix,
|
||||
ArrayStatement::parse,
|
||||
StringNode::parse,
|
||||
RegexNode::parse,
|
||||
NumberNode::parse,
|
||||
ChangeNode::parsePrefixDecrease,
|
||||
ChangeNode::parsePrefixIncrease,
|
||||
OperationNode::parsePrefix,
|
||||
ArrayNode::parse,
|
||||
JavaScript::parseParens,
|
||||
CallStatement::parseNew,
|
||||
TypeofStatement::parse,
|
||||
DiscardStatement::parse,
|
||||
DeleteStatement::parse,
|
||||
VariableStatement::parse
|
||||
CallNode::parseNew,
|
||||
TypeofNode::parse,
|
||||
DiscardNode::parse,
|
||||
DeleteNode::parse,
|
||||
VariableNode::parse
|
||||
);
|
||||
}
|
||||
|
||||
public static ParseRes<? extends Statement> parseLiteral(Source src, int i) {
|
||||
public static ParseRes<? extends Node> parseLiteral(Source src, int i) {
|
||||
var n = Parsing.skipEmpty(src, i);
|
||||
var loc = src.loc(i + n);
|
||||
|
||||
@ -100,20 +100,20 @@ public class JavaScript {
|
||||
if (!id.isSuccess()) return id.chainError();
|
||||
n += id.n;
|
||||
|
||||
if (id.result.equals("true")) return ParseRes.res(new BoolStatement(loc, true), n);
|
||||
if (id.result.equals("false")) return ParseRes.res(new BoolStatement(loc, false), n);
|
||||
if (id.result.equals("undefined")) return ParseRes.res(new DiscardStatement(loc, null), n);
|
||||
if (id.result.equals("null")) return ParseRes.res(new NullStatement(loc), n);
|
||||
if (id.result.equals("this")) return ParseRes.res(new VariableIndexStatement(loc, 0), n);
|
||||
if (id.result.equals("arguments")) return ParseRes.res(new VariableIndexStatement(loc, 1), n);
|
||||
if (id.result.equals("globalThis")) return ParseRes.res(new GlobalThisStatement(loc), n);
|
||||
if (id.result.equals("true")) return ParseRes.res(new BoolNode(loc, true), n);
|
||||
if (id.result.equals("false")) return ParseRes.res(new BoolNode(loc, false), n);
|
||||
if (id.result.equals("undefined")) return ParseRes.res(new DiscardNode(loc, null), n);
|
||||
if (id.result.equals("null")) return ParseRes.res(new NullNode(loc), n);
|
||||
if (id.result.equals("this")) return ParseRes.res(new VariableIndexNode(loc, 0), n);
|
||||
if (id.result.equals("arguments")) return ParseRes.res(new VariableIndexNode(loc, 1), n);
|
||||
if (id.result.equals("globalThis")) return ParseRes.res(new GlobalThisNode(loc), n);
|
||||
|
||||
return ParseRes.failed();
|
||||
}
|
||||
|
||||
public static ParseRes<? extends Statement> parseExpression(Source src, int i, int precedence, boolean statement) {
|
||||
public static ParseRes<? extends Node> parseExpression(Source src, int i, int precedence, boolean statement) {
|
||||
var n = Parsing.skipEmpty(src, i);
|
||||
Statement prev = null;
|
||||
Node prev = null;
|
||||
|
||||
while (true) {
|
||||
if (prev == null) {
|
||||
@ -127,17 +127,17 @@ public class JavaScript {
|
||||
}
|
||||
else {
|
||||
var _prev = prev;
|
||||
ParseRes<Statement> res = ParseRes.first(src, i + n,
|
||||
(s, j) -> OperationStatement.parseInstanceof(s, j, _prev, precedence),
|
||||
(s, j) -> OperationStatement.parseIn(s, j, _prev, precedence),
|
||||
(s, j) -> ChangeStatement.parsePostfixIncrease(s, j, _prev, precedence),
|
||||
(s, j) -> ChangeStatement.parsePostfixDecrease(s, j, _prev, precedence),
|
||||
(s, j) -> OperationStatement.parseOperator(s, j, _prev, precedence),
|
||||
(s, j) -> IfStatement.parseTernary(s, j, _prev, precedence),
|
||||
(s, j) -> IndexStatement.parseMember(s, j, _prev, precedence),
|
||||
(s, j) -> IndexStatement.parseIndex(s, j, _prev, precedence),
|
||||
(s, j) -> CallStatement.parseCall(s, j, _prev, precedence),
|
||||
(s, j) -> CompoundStatement.parseComma(s, j, _prev, precedence)
|
||||
ParseRes<Node> res = ParseRes.first(src, i + n,
|
||||
(s, j) -> OperationNode.parseInstanceof(s, j, _prev, precedence),
|
||||
(s, j) -> OperationNode.parseIn(s, j, _prev, precedence),
|
||||
(s, j) -> ChangeNode.parsePostfixIncrease(s, j, _prev, precedence),
|
||||
(s, j) -> ChangeNode.parsePostfixDecrease(s, j, _prev, precedence),
|
||||
(s, j) -> OperationNode.parseOperator(s, j, _prev, precedence),
|
||||
(s, j) -> IfNode.parseTernary(s, j, _prev, precedence),
|
||||
(s, j) -> IndexNode.parseMember(s, j, _prev, precedence),
|
||||
(s, j) -> IndexNode.parseIndex(s, j, _prev, precedence),
|
||||
(s, j) -> CallNode.parseCall(s, j, _prev, precedence),
|
||||
(s, j) -> CompoundNode.parseComma(s, j, _prev, precedence)
|
||||
);
|
||||
|
||||
if (res.isSuccess()) {
|
||||
@ -155,11 +155,11 @@ public class JavaScript {
|
||||
else return ParseRes.res(prev, n);
|
||||
}
|
||||
|
||||
public static ParseRes<? extends Statement> parseExpression(Source src, int i, int precedence) {
|
||||
public static ParseRes<? extends Node> parseExpression(Source src, int i, int precedence) {
|
||||
return parseExpression(src, i, precedence, false);
|
||||
}
|
||||
|
||||
public static ParseRes<? extends Statement> parseExpressionStatement(Source src, int i) {
|
||||
public static ParseRes<? extends Node> parseExpressionStatement(Source src, int i) {
|
||||
var res = parseExpression(src, i, 0, true);
|
||||
if (!res.isSuccess()) return res.chainError();
|
||||
|
||||
@ -169,29 +169,29 @@ public class JavaScript {
|
||||
return res.addN(end.n);
|
||||
}
|
||||
|
||||
public static ParseRes<? extends Statement> parseStatement(Source src, int i) {
|
||||
public static ParseRes<? extends Node> parseStatement(Source src, int i) {
|
||||
var n = Parsing.skipEmpty(src, i);
|
||||
|
||||
if (src.is(i + n, ";")) return ParseRes.res(new DiscardStatement(src.loc(i+ n), null), n + 1);
|
||||
if (src.is(i + n, ";")) return ParseRes.res(new DiscardNode(src.loc(i+ n), null), n + 1);
|
||||
if (Parsing.isIdentifier(src, i + n, "with")) return ParseRes.error(src.loc(i + n), "'with' statements are not allowed.");
|
||||
|
||||
ParseRes<? extends Statement> res = ParseRes.first(src, i + n,
|
||||
VariableDeclareStatement::parse,
|
||||
ReturnStatement::parse,
|
||||
ThrowStatement::parse,
|
||||
ContinueStatement::parse,
|
||||
BreakStatement::parse,
|
||||
DebugStatement::parse,
|
||||
IfStatement::parse,
|
||||
WhileStatement::parse,
|
||||
SwitchStatement::parse,
|
||||
ForStatement::parse,
|
||||
ForInStatement::parse,
|
||||
ForOfStatement::parse,
|
||||
DoWhileStatement::parse,
|
||||
TryStatement::parse,
|
||||
CompoundStatement::parse,
|
||||
(s, j) -> FunctionStatement.parseFunction(s, j, true),
|
||||
ParseRes<? extends Node> res = ParseRes.first(src, i + n,
|
||||
VariableDeclareNode::parse,
|
||||
ReturnNode::parse,
|
||||
ThrowNode::parse,
|
||||
ContinueNode::parse,
|
||||
BreakNode::parse,
|
||||
DebugNode::parse,
|
||||
IfNode::parse,
|
||||
WhileNode::parse,
|
||||
SwitchNode::parse,
|
||||
ForNode::parse,
|
||||
ForInNode::parse,
|
||||
ForOfNode::parse,
|
||||
DoWhileNode::parse,
|
||||
TryNode::parse,
|
||||
CompoundNode::parse,
|
||||
(s, j) -> FunctionNode.parseFunction(s, j, true),
|
||||
JavaScript::parseExpressionStatement
|
||||
);
|
||||
return res.addN(n);
|
||||
@ -247,9 +247,9 @@ public class JavaScript {
|
||||
return ParseRes.res(args, n);
|
||||
}
|
||||
|
||||
public static Statement[] parse(Environment env, Filename filename, String raw) {
|
||||
public static Node[] parse(Environment env, Filename filename, String raw) {
|
||||
var src = new Source(env, filename, raw);
|
||||
var list = new ArrayList<Statement>();
|
||||
var list = new ArrayList<Node>();
|
||||
int i = 0;
|
||||
|
||||
while (true) {
|
||||
@ -265,23 +265,23 @@ public class JavaScript {
|
||||
list.add(res.result);
|
||||
}
|
||||
|
||||
return list.toArray(Statement[]::new);
|
||||
return list.toArray(Node[]::new);
|
||||
}
|
||||
|
||||
public static boolean checkVarName(String name) {
|
||||
return !JavaScript.reserved.contains(name);
|
||||
}
|
||||
|
||||
public static CompileResult compile(Statement ...statements) {
|
||||
public static CompileResult compile(Node ...statements) {
|
||||
var target = new CompileResult(new LocalScopeRecord());
|
||||
var stm = new CompoundStatement(null, true, statements);
|
||||
var stm = new CompoundNode(null, true, statements);
|
||||
|
||||
target.scope.define("this");
|
||||
target.scope.define("arguments");
|
||||
|
||||
try {
|
||||
stm.compile(target, true);
|
||||
FunctionStatement.checkBreakAndCont(target, 0);
|
||||
FunctionNode.checkBreakAndCont(target, 0);
|
||||
}
|
||||
catch (SyntaxException e) {
|
||||
target = new CompileResult(new LocalScopeRecord());
|
||||
|
@ -3,7 +3,7 @@ package me.topchetoeu.jscript.compilation;
|
||||
import me.topchetoeu.jscript.common.Instruction.BreakpointType;
|
||||
import me.topchetoeu.jscript.common.parsing.Location;
|
||||
|
||||
public abstract class Statement {
|
||||
public abstract class Node {
|
||||
private Location _loc;
|
||||
|
||||
public boolean pure() { return false; }
|
||||
@ -21,7 +21,7 @@ public abstract class Statement {
|
||||
public Location loc() { return _loc; }
|
||||
public void setLoc(Location loc) { _loc = loc; }
|
||||
|
||||
protected Statement(Location loc) {
|
||||
protected Node(Location loc) {
|
||||
this._loc = loc;
|
||||
}
|
||||
}
|
@ -3,7 +3,7 @@ package me.topchetoeu.jscript.compilation;
|
||||
import me.topchetoeu.jscript.common.Instruction;
|
||||
import me.topchetoeu.jscript.runtime.exceptions.SyntaxException;
|
||||
|
||||
public class ThrowSyntaxStatement extends Statement {
|
||||
public class ThrowSyntaxNode extends Node {
|
||||
public final String name;
|
||||
|
||||
@Override
|
||||
@ -11,7 +11,7 @@ public class ThrowSyntaxStatement extends Statement {
|
||||
target.add(Instruction.throwSyntax(name));
|
||||
}
|
||||
|
||||
public ThrowSyntaxStatement(SyntaxException e) {
|
||||
public ThrowSyntaxNode(SyntaxException e) {
|
||||
super(e.loc);
|
||||
this.name = e.msg;
|
||||
}
|
@ -9,15 +9,15 @@ 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.values.FunctionStatement;
|
||||
import me.topchetoeu.jscript.compilation.values.FunctionNode;
|
||||
|
||||
public class VariableDeclareStatement extends Statement {
|
||||
public class VariableDeclareNode extends Node {
|
||||
public static class Pair {
|
||||
public final String name;
|
||||
public final Statement value;
|
||||
public final Node value;
|
||||
public final Location location;
|
||||
|
||||
public Pair(String name, Statement value, Location location) {
|
||||
public Pair(String name, Node value, Location location) {
|
||||
this.name = name;
|
||||
this.value = value;
|
||||
this.location = location;
|
||||
@ -41,7 +41,7 @@ public class VariableDeclareStatement extends Statement {
|
||||
if (key instanceof String) target.add(Instruction.makeVar((String)key));
|
||||
|
||||
if (entry.value != null) {
|
||||
FunctionStatement.compileWithName(entry.value, target, true, entry.name, BreakpointType.STEP_OVER);
|
||||
FunctionNode.compileWithName(entry.value, target, true, entry.name, BreakpointType.STEP_OVER);
|
||||
target.add(Instruction.storeVar(key));
|
||||
}
|
||||
}
|
||||
@ -49,12 +49,12 @@ public class VariableDeclareStatement extends Statement {
|
||||
if (pollute) target.add(Instruction.pushUndefined());
|
||||
}
|
||||
|
||||
public VariableDeclareStatement(Location loc, List<Pair> values) {
|
||||
public VariableDeclareNode(Location loc, List<Pair> values) {
|
||||
super(loc);
|
||||
this.values = values;
|
||||
}
|
||||
|
||||
public static ParseRes<VariableDeclareStatement> parse(Source src, int i) {
|
||||
public static ParseRes<VariableDeclareNode> parse(Source src, int i) {
|
||||
var n = Parsing.skipEmpty(src, i);
|
||||
var loc = src.loc(i + n);
|
||||
|
||||
@ -66,7 +66,7 @@ public class VariableDeclareStatement extends Statement {
|
||||
var end = JavaScript.parseStatementEnd(src, i + n);
|
||||
if (end.isSuccess()) {
|
||||
n += end.n;
|
||||
return ParseRes.res(new VariableDeclareStatement(loc, res), n);
|
||||
return ParseRes.res(new VariableDeclareNode(loc, res), n);
|
||||
}
|
||||
|
||||
while (true) {
|
||||
@ -79,7 +79,7 @@ public class VariableDeclareStatement extends Statement {
|
||||
return ParseRes.error(src.loc(i + n), String.format("Unexpected identifier '%s'", name.result));
|
||||
}
|
||||
|
||||
Statement val = null;
|
||||
Node val = null;
|
||||
n += Parsing.skipEmpty(src, i + n);
|
||||
|
||||
if (src.is(i + n, "=")) {
|
||||
@ -104,7 +104,7 @@ public class VariableDeclareStatement extends Statement {
|
||||
|
||||
if (end.isSuccess()) {
|
||||
n += end.n;
|
||||
return ParseRes.res(new VariableDeclareStatement(loc, 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");
|
||||
}
|
@ -7,9 +7,9 @@ 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.Statement;
|
||||
import me.topchetoeu.jscript.compilation.Node;
|
||||
|
||||
public class BreakStatement extends Statement {
|
||||
public class BreakNode extends Node {
|
||||
public final String label;
|
||||
|
||||
@Override public void compile(CompileResult target, boolean pollute) {
|
||||
@ -17,12 +17,12 @@ public class BreakStatement extends Statement {
|
||||
if (pollute) target.add(Instruction.pushUndefined());
|
||||
}
|
||||
|
||||
public BreakStatement(Location loc, String label) {
|
||||
public BreakNode(Location loc, String label) {
|
||||
super(loc);
|
||||
this.label = label;
|
||||
}
|
||||
|
||||
public static ParseRes<BreakStatement> parse(Source src, int i) {
|
||||
public static ParseRes<BreakNode> parse(Source src, int i) {
|
||||
var n = Parsing.skipEmpty(src, i);
|
||||
var loc = src.loc(i + n);
|
||||
|
||||
@ -32,7 +32,7 @@ public class BreakStatement extends Statement {
|
||||
var end = JavaScript.parseStatementEnd(src, i + n);
|
||||
if (end.isSuccess()) {
|
||||
n += end.n;
|
||||
return ParseRes.res(new BreakStatement(loc, null), n);
|
||||
return ParseRes.res(new BreakNode(loc, null), n);
|
||||
}
|
||||
|
||||
var label = Parsing.parseIdentifier(src, i + n);
|
||||
@ -42,7 +42,7 @@ public class BreakStatement extends Statement {
|
||||
end = JavaScript.parseStatementEnd(src, i + n);
|
||||
if (end.isSuccess()) {
|
||||
n += end.n;
|
||||
return ParseRes.res(new BreakStatement(loc, label.result), n);
|
||||
return ParseRes.res(new BreakNode(loc, label.result), n);
|
||||
}
|
||||
else return end.chainError(src.loc(i + n), "Expected end of statement");
|
||||
}
|
@ -7,9 +7,9 @@ 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.Statement;
|
||||
import me.topchetoeu.jscript.compilation.Node;
|
||||
|
||||
public class ContinueStatement extends Statement {
|
||||
public class ContinueNode extends Node {
|
||||
public final String label;
|
||||
|
||||
@Override public void compile(CompileResult target, boolean pollute) {
|
||||
@ -17,12 +17,12 @@ public class ContinueStatement extends Statement {
|
||||
if (pollute) target.add(Instruction.pushUndefined());
|
||||
}
|
||||
|
||||
public ContinueStatement(Location loc, String label) {
|
||||
public ContinueNode(Location loc, String label) {
|
||||
super(loc);
|
||||
this.label = label;
|
||||
}
|
||||
|
||||
public static ParseRes<ContinueStatement> parse(Source src, int i) {
|
||||
public static ParseRes<ContinueNode> parse(Source src, int i) {
|
||||
var n = Parsing.skipEmpty(src, i);
|
||||
var loc = src.loc(i + n);
|
||||
|
||||
@ -32,7 +32,7 @@ public class ContinueStatement extends Statement {
|
||||
var end = JavaScript.parseStatementEnd(src, i + n);
|
||||
if (end.isSuccess()) {
|
||||
n += end.n;
|
||||
return ParseRes.res(new ContinueStatement(loc, null), n);
|
||||
return ParseRes.res(new ContinueNode(loc, null), n);
|
||||
}
|
||||
|
||||
var label = Parsing.parseIdentifier(src, i + n);
|
||||
@ -42,7 +42,7 @@ public class ContinueStatement extends Statement {
|
||||
end = JavaScript.parseStatementEnd(src, i + n);
|
||||
if (end.isSuccess()) {
|
||||
n += end.n;
|
||||
return ParseRes.res(new ContinueStatement(loc, label.result), n);
|
||||
return ParseRes.res(new ContinueNode(loc, label.result), n);
|
||||
}
|
||||
else return end.chainError(src.loc(i + n), "Expected end of statement");
|
||||
}
|
@ -7,19 +7,19 @@ 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.Statement;
|
||||
import me.topchetoeu.jscript.compilation.Node;
|
||||
|
||||
public class DebugStatement extends Statement {
|
||||
public class DebugNode extends Node {
|
||||
@Override public void compile(CompileResult target, boolean pollute) {
|
||||
target.add(Instruction.debug());
|
||||
if (pollute) target.add(Instruction.pushUndefined());
|
||||
}
|
||||
|
||||
public DebugStatement(Location loc) {
|
||||
public DebugNode(Location loc) {
|
||||
super(loc);
|
||||
}
|
||||
|
||||
public static ParseRes<DebugStatement> parse(Source src, int i) {
|
||||
public static ParseRes<DebugNode> parse(Source src, int i) {
|
||||
var n = Parsing.skipEmpty(src, i);
|
||||
var loc = src.loc(i + n);
|
||||
|
||||
@ -29,7 +29,7 @@ public class DebugStatement extends Statement {
|
||||
var end = JavaScript.parseStatementEnd(src, i + n);
|
||||
if (end.isSuccess()) {
|
||||
n += end.n;
|
||||
return ParseRes.res(new DebugStatement(loc), n);
|
||||
return ParseRes.res(new DebugNode(loc), n);
|
||||
}
|
||||
else return end.chainError(src.loc(i + n), "Expected end of statement");
|
||||
}
|
@ -7,14 +7,14 @@ 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.Statement;
|
||||
import me.topchetoeu.jscript.compilation.values.VariableStatement;
|
||||
import me.topchetoeu.jscript.compilation.values.constants.BoolStatement;
|
||||
import me.topchetoeu.jscript.compilation.values.operations.IndexStatement;
|
||||
import me.topchetoeu.jscript.compilation.Node;
|
||||
import me.topchetoeu.jscript.compilation.values.VariableNode;
|
||||
import me.topchetoeu.jscript.compilation.values.constants.BoolNode;
|
||||
import me.topchetoeu.jscript.compilation.values.operations.IndexNode;
|
||||
|
||||
public class DeleteStatement extends Statement {
|
||||
public final Statement key;
|
||||
public final Statement value;
|
||||
public class DeleteNode extends Node {
|
||||
public final Node key;
|
||||
public final Node value;
|
||||
|
||||
@Override
|
||||
public void compile(CompileResult target, boolean pollute) {
|
||||
@ -25,7 +25,7 @@ public class DeleteStatement extends Statement {
|
||||
if (pollute) target.add(Instruction.pushValue(true));
|
||||
}
|
||||
|
||||
public static ParseRes<? extends Statement> parse(Source src, int i) {
|
||||
public static ParseRes<? extends Node> parse(Source src, int i) {
|
||||
var n = Parsing.skipEmpty(src, i);
|
||||
var loc = src.loc(i + n);
|
||||
|
||||
@ -36,17 +36,17 @@ public class DeleteStatement extends Statement {
|
||||
if (!valRes.isSuccess()) return valRes.chainError(src.loc(i + n), "Expected a value after 'delete'");
|
||||
n += valRes.n;
|
||||
|
||||
if (valRes.result instanceof IndexStatement) {
|
||||
var index = (IndexStatement)valRes.result;
|
||||
return ParseRes.res(new DeleteStatement(loc, index.index, index.object), n);
|
||||
if (valRes.result instanceof IndexNode) {
|
||||
var index = (IndexNode)valRes.result;
|
||||
return ParseRes.res(new DeleteNode(loc, index.index, index.object), n);
|
||||
}
|
||||
else if (valRes.result instanceof VariableStatement) {
|
||||
else if (valRes.result instanceof VariableNode) {
|
||||
return ParseRes.error(src.loc(i + n), "A variable may not be deleted");
|
||||
}
|
||||
else return ParseRes.res(new BoolStatement(loc, true), n);
|
||||
else return ParseRes.res(new BoolNode(loc, true), n);
|
||||
}
|
||||
|
||||
public DeleteStatement(Location loc, Statement key, Statement value) {
|
||||
public DeleteNode(Location loc, Node key, Node value) {
|
||||
super(loc);
|
||||
this.key = key;
|
||||
this.value = value;
|
@ -8,10 +8,10 @@ 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.Statement;
|
||||
import me.topchetoeu.jscript.compilation.Node;
|
||||
|
||||
public class DoWhileStatement extends Statement {
|
||||
public final Statement condition, body;
|
||||
public class DoWhileNode extends Node {
|
||||
public final Node condition, body;
|
||||
public final String label;
|
||||
|
||||
@Override
|
||||
@ -27,22 +27,22 @@ public class DoWhileStatement extends Statement {
|
||||
condition.compile(target, true, BreakpointType.STEP_OVER);
|
||||
int end = target.size();
|
||||
|
||||
WhileStatement.replaceBreaks(target, label, start, mid - 1, mid, end + 1);
|
||||
WhileNode.replaceBreaks(target, label, start, mid - 1, mid, end + 1);
|
||||
target.add(Instruction.jmpIf(start - end));
|
||||
}
|
||||
|
||||
public DoWhileStatement(Location loc, String label, Statement condition, Statement body) {
|
||||
public DoWhileNode(Location loc, String label, Node condition, Node body) {
|
||||
super(loc);
|
||||
this.label = label;
|
||||
this.condition = condition;
|
||||
this.body = body;
|
||||
}
|
||||
|
||||
public static ParseRes<DoWhileStatement> parse(Source src, int i) {
|
||||
public static ParseRes<DoWhileNode> parse(Source src, int i) {
|
||||
var n = Parsing.skipEmpty(src, i);
|
||||
var loc = src.loc(i + n);
|
||||
|
||||
var labelRes = WhileStatement.parseLabel(src, i + n);
|
||||
var labelRes = WhileNode.parseLabel(src, i + n);
|
||||
n += labelRes.n;
|
||||
|
||||
if (!Parsing.isIdentifier(src, i + n, "do")) return ParseRes.failed();
|
||||
@ -70,7 +70,7 @@ public class DoWhileStatement extends Statement {
|
||||
var end = JavaScript.parseStatementEnd(src, i + n);
|
||||
if (end.isSuccess()) {
|
||||
n += end.n;
|
||||
return ParseRes.res(new DoWhileStatement(loc, labelRes.result, condRes.result, bodyRes.result), n);
|
||||
return ParseRes.res(new DoWhileNode(loc, labelRes.result, condRes.result, bodyRes.result), n);
|
||||
}
|
||||
else return end.chainError(src.loc(i + n), "Expected end of statement");
|
||||
}
|
@ -9,12 +9,12 @@ 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.Statement;
|
||||
import me.topchetoeu.jscript.compilation.Node;
|
||||
|
||||
public class ForInStatement extends Statement {
|
||||
public class ForInNode extends Node {
|
||||
public final String varName;
|
||||
public final boolean isDeclaration;
|
||||
public final Statement object, body;
|
||||
public final Node object, body;
|
||||
public final String label;
|
||||
public final Location varLocation;
|
||||
|
||||
@ -45,7 +45,7 @@ public class ForInStatement extends Statement {
|
||||
|
||||
int end = target.size();
|
||||
|
||||
WhileStatement.replaceBreaks(target, label, mid + 1, end, start, end + 1);
|
||||
WhileNode.replaceBreaks(target, label, mid + 1, end, start, end + 1);
|
||||
|
||||
target.add(Instruction.jmp(start - end));
|
||||
target.add(Instruction.discard());
|
||||
@ -53,7 +53,7 @@ public class ForInStatement extends Statement {
|
||||
if (pollute) target.add(Instruction.pushUndefined());
|
||||
}
|
||||
|
||||
public ForInStatement(Location loc, Location varLocation, String label, boolean isDecl, String varName, Statement object, Statement body) {
|
||||
public ForInNode(Location loc, Location varLocation, String label, boolean isDecl, String varName, Node object, Node body) {
|
||||
super(loc);
|
||||
this.varLocation = varLocation;
|
||||
this.label = label;
|
||||
@ -63,11 +63,11 @@ public class ForInStatement extends Statement {
|
||||
this.body = body;
|
||||
}
|
||||
|
||||
public static ParseRes<ForInStatement> parse(Source src, int i) {
|
||||
public static ParseRes<ForInNode> parse(Source src, int i) {
|
||||
var n = Parsing.skipEmpty(src, i);
|
||||
var loc = src.loc(i + n);
|
||||
|
||||
var label = WhileStatement.parseLabel(src, i + n);
|
||||
var label = WhileNode.parseLabel(src, i + n);
|
||||
n += label.n;
|
||||
n += Parsing.skipEmpty(src, i + n);
|
||||
|
||||
@ -103,6 +103,6 @@ public class ForInStatement extends Statement {
|
||||
if (!bodyRes.isSuccess()) return bodyRes.chainError(src.loc(i + n), "Expected a for-in body");
|
||||
n += bodyRes.n;
|
||||
|
||||
return ParseRes.res(new ForInStatement(loc, nameLoc, label.result, isDecl, name.result, obj.result, bodyRes.result), n);
|
||||
return ParseRes.res(new ForInNode(loc, nameLoc, label.result, isDecl, name.result, obj.result, bodyRes.result), n);
|
||||
}
|
||||
}
|
@ -8,12 +8,12 @@ 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.Statement;
|
||||
import me.topchetoeu.jscript.compilation.VariableDeclareStatement;
|
||||
import me.topchetoeu.jscript.compilation.values.operations.DiscardStatement;
|
||||
import me.topchetoeu.jscript.compilation.Node;
|
||||
import me.topchetoeu.jscript.compilation.VariableDeclareNode;
|
||||
import me.topchetoeu.jscript.compilation.values.operations.DiscardNode;
|
||||
|
||||
public class ForStatement extends Statement {
|
||||
public final Statement declaration, assignment, condition, body;
|
||||
public class ForNode extends Node {
|
||||
public final Node declaration, assignment, condition, body;
|
||||
public final String label;
|
||||
|
||||
@Override
|
||||
@ -33,14 +33,14 @@ public class ForStatement extends Statement {
|
||||
assignment.compile(target, false, BreakpointType.STEP_OVER);
|
||||
int end = target.size();
|
||||
|
||||
WhileStatement.replaceBreaks(target, label, mid + 1, end, beforeAssign, end + 1);
|
||||
WhileNode.replaceBreaks(target, label, mid + 1, end, beforeAssign, end + 1);
|
||||
|
||||
target.add(Instruction.jmp(start - end));
|
||||
target.set(mid, Instruction.jmpIfNot(end - mid + 1));
|
||||
if (pollute) target.add(Instruction.pushUndefined());
|
||||
}
|
||||
|
||||
public ForStatement(Location loc, String label, Statement declaration, Statement condition, Statement assignment, Statement body) {
|
||||
public ForNode(Location loc, String label, Node declaration, Node condition, Node assignment, Node body) {
|
||||
super(loc);
|
||||
this.label = label;
|
||||
this.declaration = declaration;
|
||||
@ -49,13 +49,13 @@ public class ForStatement extends Statement {
|
||||
this.body = body;
|
||||
}
|
||||
|
||||
private static ParseRes<Statement> parseSemicolon(Source src, int i) {
|
||||
private static ParseRes<Node> parseSemicolon(Source src, int i) {
|
||||
var n = Parsing.skipEmpty(src, i);
|
||||
|
||||
if (!src.is(i + n, ";")) return ParseRes.failed();
|
||||
else return ParseRes.res(new DiscardStatement(src.loc(i), null), n + 1);
|
||||
else return ParseRes.res(new DiscardNode(src.loc(i), null), n + 1);
|
||||
}
|
||||
private static ParseRes<Statement> parseCondition(Source src, int i) {
|
||||
private static ParseRes<Node> parseCondition(Source src, int i) {
|
||||
var n = Parsing.skipEmpty(src, i);
|
||||
|
||||
var res = JavaScript.parseExpression(src, i + n, 0);
|
||||
@ -66,15 +66,15 @@ public class ForStatement extends Statement {
|
||||
if (!src.is(i + n, ";")) return ParseRes.error(src.loc(i + n), "Expected a semicolon");
|
||||
else return ParseRes.res(res.result, n + 1);
|
||||
}
|
||||
private static ParseRes<? extends Statement> parseUpdater(Source src, int i) {
|
||||
private static ParseRes<? extends Node> parseUpdater(Source src, int i) {
|
||||
return JavaScript.parseExpression(src, i, 0);
|
||||
}
|
||||
|
||||
public static ParseRes<ForStatement> parse(Source src, int i) {
|
||||
public static ParseRes<ForNode> parse(Source src, int i) {
|
||||
var n = Parsing.skipEmpty(src, i);
|
||||
var loc = src.loc(i + n);
|
||||
|
||||
var labelRes = WhileStatement.parseLabel(src, i + n);
|
||||
var labelRes = WhileNode.parseLabel(src, i + n);
|
||||
n += labelRes.n;
|
||||
n += Parsing.skipEmpty(src, i + n);
|
||||
|
||||
@ -85,17 +85,17 @@ public class ForStatement extends Statement {
|
||||
if (!src.is(i + n, "(")) return ParseRes.error(src.loc(i + n), "Expected a open paren after 'for'");
|
||||
n++;
|
||||
|
||||
ParseRes<Statement> decl = ParseRes.first(src, i + n,
|
||||
ForStatement::parseSemicolon,
|
||||
VariableDeclareStatement::parse,
|
||||
ForStatement::parseCondition
|
||||
ParseRes<Node> decl = ParseRes.first(src, i + n,
|
||||
ForNode::parseSemicolon,
|
||||
VariableDeclareNode::parse,
|
||||
ForNode::parseCondition
|
||||
);
|
||||
if (!decl.isSuccess()) return decl.chainError(src.loc(i + n), "Expected a declaration or an expression");
|
||||
n += decl.n;
|
||||
|
||||
ParseRes<Statement> cond = ParseRes.first(src, i + n,
|
||||
ForStatement::parseSemicolon,
|
||||
ForStatement::parseCondition
|
||||
ParseRes<Node> cond = ParseRes.first(src, i + n,
|
||||
ForNode::parseSemicolon,
|
||||
ForNode::parseCondition
|
||||
);
|
||||
if (!cond.isSuccess()) return cond.chainError(src.loc(i + n), "Expected a condition");
|
||||
n += cond.n;
|
||||
@ -112,6 +112,6 @@ public class ForStatement extends Statement {
|
||||
if (!body.isSuccess()) return body.chainError(src.loc(i + n), "Expected a for body.");
|
||||
n += body.n;
|
||||
|
||||
return ParseRes.res(new ForStatement(loc, labelRes.result, decl.result, cond.result, update.result, body.result), n);
|
||||
return ParseRes.res(new ForNode(loc, labelRes.result, decl.result, cond.result, update.result, body.result), n);
|
||||
}
|
||||
}
|
@ -8,12 +8,12 @@ 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.Statement;
|
||||
import me.topchetoeu.jscript.compilation.Node;
|
||||
|
||||
public class ForOfStatement extends Statement {
|
||||
public class ForOfNode extends Node {
|
||||
public final String varName;
|
||||
public final boolean isDeclaration;
|
||||
public final Statement iterable, body;
|
||||
public final Node iterable, body;
|
||||
public final String label;
|
||||
public final Location varLocation;
|
||||
|
||||
@ -56,7 +56,7 @@ public class ForOfStatement extends Statement {
|
||||
|
||||
int end = target.size();
|
||||
|
||||
WhileStatement.replaceBreaks(target, label, mid + 1, end, start, end + 1);
|
||||
WhileNode.replaceBreaks(target, label, mid + 1, end, start, end + 1);
|
||||
|
||||
target.add(Instruction.jmp(start - end));
|
||||
target.add(Instruction.discard());
|
||||
@ -65,7 +65,7 @@ public class ForOfStatement extends Statement {
|
||||
if (pollute) target.add(Instruction.pushUndefined());
|
||||
}
|
||||
|
||||
public ForOfStatement(Location loc, Location varLocation, String label, boolean isDecl, String varName, Statement object, Statement body) {
|
||||
public ForOfNode(Location loc, Location varLocation, String label, boolean isDecl, String varName, Node object, Node body) {
|
||||
super(loc);
|
||||
this.varLocation = varLocation;
|
||||
this.label = label;
|
||||
@ -75,11 +75,11 @@ public class ForOfStatement extends Statement {
|
||||
this.body = body;
|
||||
}
|
||||
|
||||
public static ParseRes<ForOfStatement> parse(Source src, int i) {
|
||||
public static ParseRes<ForOfNode> parse(Source src, int i) {
|
||||
var n = Parsing.skipEmpty(src, i);
|
||||
var loc = src.loc(i + n);
|
||||
|
||||
var label = WhileStatement.parseLabel(src, i + n);
|
||||
var label = WhileNode.parseLabel(src, i + n);
|
||||
n += label.n;
|
||||
n += Parsing.skipEmpty(src, i + n);
|
||||
|
||||
@ -115,6 +115,6 @@ public class ForOfStatement extends Statement {
|
||||
if (!bodyRes.isSuccess()) return bodyRes.chainError(src.loc(i + n), "Expected a for-of body");
|
||||
n += bodyRes.n;
|
||||
|
||||
return ParseRes.res(new ForOfStatement(loc, nameLoc, label.result, isDecl, name.result, obj.result, bodyRes.result), n);
|
||||
return ParseRes.res(new ForOfNode(loc, nameLoc, label.result, isDecl, name.result, obj.result, bodyRes.result), n);
|
||||
}
|
||||
}
|
@ -8,10 +8,10 @@ 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.Statement;
|
||||
import me.topchetoeu.jscript.compilation.Node;
|
||||
|
||||
public class IfStatement extends Statement {
|
||||
public final Statement condition, body, elseBody;
|
||||
public class IfNode extends Node {
|
||||
public final Node condition, body, elseBody;
|
||||
|
||||
@Override
|
||||
public void declare(CompileResult target) {
|
||||
@ -43,14 +43,14 @@ public class IfStatement extends Statement {
|
||||
compile(target, pollute, BreakpointType.STEP_IN);
|
||||
}
|
||||
|
||||
public IfStatement(Location loc, Statement condition, Statement body, Statement elseBody) {
|
||||
public IfNode(Location loc, Node condition, Node body, Node elseBody) {
|
||||
super(loc);
|
||||
this.condition = condition;
|
||||
this.body = body;
|
||||
this.elseBody = elseBody;
|
||||
}
|
||||
|
||||
public static ParseRes<IfStatement> parseTernary(Source src, int i, Statement prev, int precedence) {
|
||||
public static ParseRes<IfNode> parseTernary(Source src, int i, Node prev, int precedence) {
|
||||
if (precedence > 2) return ParseRes.failed();
|
||||
|
||||
var n = Parsing.skipEmpty(src, i);
|
||||
@ -71,9 +71,9 @@ public class IfStatement extends Statement {
|
||||
if (!b.isSuccess()) return b.chainError(src.loc(i + n), "Expected a second value after the ternary operator.");
|
||||
n += b.n;
|
||||
|
||||
return ParseRes.res(new IfStatement(loc, prev, a.result, b.result), n);
|
||||
return ParseRes.res(new IfNode(loc, prev, a.result, b.result), n);
|
||||
}
|
||||
public static ParseRes<IfStatement> parse(Source src, int i) {
|
||||
public static ParseRes<IfNode> parse(Source src, int i) {
|
||||
var n = Parsing.skipEmpty(src, i);
|
||||
var loc = src.loc(i + n);
|
||||
|
||||
@ -97,14 +97,14 @@ public class IfStatement extends Statement {
|
||||
n += res.n;
|
||||
|
||||
var elseKw = Parsing.parseIdentifier(src, i + n, "else");
|
||||
if (!elseKw.isSuccess()) return ParseRes.res(new IfStatement(loc, condRes.result, res.result, null), n);
|
||||
if (!elseKw.isSuccess()) return ParseRes.res(new IfNode(loc, condRes.result, res.result, null), n);
|
||||
n += elseKw.n;
|
||||
|
||||
var elseRes = JavaScript.parseStatement(src, i + n);
|
||||
if (!elseRes.isSuccess()) return elseRes.chainError(src.loc(i + n), "Expected an else body.");
|
||||
n += elseRes.n;
|
||||
|
||||
return ParseRes.res(new IfStatement(loc, condRes.result, res.result, elseRes.result), n);
|
||||
return ParseRes.res(new IfNode(loc, condRes.result, res.result, elseRes.result), n);
|
||||
}
|
||||
|
||||
}
|
@ -7,10 +7,10 @@ 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.Statement;
|
||||
import me.topchetoeu.jscript.compilation.Node;
|
||||
|
||||
public class ReturnStatement extends Statement {
|
||||
public final Statement value;
|
||||
public class ReturnNode extends Node {
|
||||
public final Node value;
|
||||
|
||||
@Override
|
||||
public void compile(CompileResult target, boolean pollute) {
|
||||
@ -19,12 +19,12 @@ public class ReturnStatement extends Statement {
|
||||
target.add(Instruction.ret()).setLocation(loc());
|
||||
}
|
||||
|
||||
public ReturnStatement(Location loc, Statement value) {
|
||||
public ReturnNode(Location loc, Node value) {
|
||||
super(loc);
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public static ParseRes<ReturnStatement> parse(Source src, int i) {
|
||||
public static ParseRes<ReturnNode> parse(Source src, int i) {
|
||||
var n = Parsing.skipEmpty(src, i);
|
||||
var loc = src.loc(i + n);
|
||||
|
||||
@ -34,7 +34,7 @@ public class ReturnStatement extends Statement {
|
||||
var end = JavaScript.parseStatementEnd(src, i + n);
|
||||
if (end.isSuccess()) {
|
||||
n += end.n;
|
||||
return ParseRes.res(new ReturnStatement(loc, null), n);
|
||||
return ParseRes.res(new ReturnNode(loc, null), n);
|
||||
}
|
||||
|
||||
var val = JavaScript.parseExpression(src, i + n, 0);
|
||||
@ -44,7 +44,7 @@ public class ReturnStatement extends Statement {
|
||||
end = JavaScript.parseStatementEnd(src, i + n);
|
||||
if (end.isSuccess()) {
|
||||
n += end.n;
|
||||
return ParseRes.res(new ReturnStatement(loc, val.result), n);
|
||||
return ParseRes.res(new ReturnNode(loc, val.result), n);
|
||||
}
|
||||
else return end.chainError(src.loc(i + n), "Expected end of statement or a return value");
|
||||
}
|
@ -13,22 +13,22 @@ 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.Statement;
|
||||
import me.topchetoeu.jscript.compilation.Node;
|
||||
|
||||
public class SwitchStatement extends Statement {
|
||||
public class SwitchNode extends Node {
|
||||
public static class SwitchCase {
|
||||
public final Statement value;
|
||||
public final Node value;
|
||||
public final int statementI;
|
||||
|
||||
public SwitchCase(Statement value, int statementI) {
|
||||
public SwitchCase(Node value, int statementI) {
|
||||
this.value = value;
|
||||
this.statementI = statementI;
|
||||
}
|
||||
}
|
||||
|
||||
public final Statement value;
|
||||
public final Node value;
|
||||
public final SwitchCase[] cases;
|
||||
public final Statement[] body;
|
||||
public final Node[] body;
|
||||
public final int defaultI;
|
||||
|
||||
@Override public void declare(CompileResult target) {
|
||||
@ -76,7 +76,7 @@ public class SwitchStatement extends Statement {
|
||||
|
||||
}
|
||||
|
||||
public SwitchStatement(Location loc, Statement value, int defaultI, SwitchCase[] cases, Statement[] body) {
|
||||
public SwitchNode(Location loc, Node value, int defaultI, SwitchCase[] cases, Node[] body) {
|
||||
super(loc);
|
||||
this.value = value;
|
||||
this.defaultI = defaultI;
|
||||
@ -84,7 +84,7 @@ public class SwitchStatement extends Statement {
|
||||
this.body = body;
|
||||
}
|
||||
|
||||
private static ParseRes<Statement> parseSwitchCase(Source src, int i) {
|
||||
private static ParseRes<Node> parseSwitchCase(Source src, int i) {
|
||||
var n = Parsing.skipEmpty(src, i);
|
||||
|
||||
if (!Parsing.isIdentifier(src, i + n, "case")) return ParseRes.failed();
|
||||
@ -112,7 +112,7 @@ public class SwitchStatement extends Statement {
|
||||
return ParseRes.res(null, n);
|
||||
}
|
||||
@SuppressWarnings("unused")
|
||||
public static ParseRes<SwitchStatement> parse(Source src, int i) {
|
||||
public static ParseRes<SwitchNode> parse(Source src, int i) {
|
||||
var n = Parsing.skipEmpty(src, i);
|
||||
var loc = src.loc(i + n);
|
||||
|
||||
@ -135,7 +135,7 @@ public class SwitchStatement extends Statement {
|
||||
n++;
|
||||
n += Parsing.skipEmpty(src, i + n);
|
||||
|
||||
var statements = new ArrayList<Statement>();
|
||||
var statements = new ArrayList<Node>();
|
||||
var cases = new ArrayList<SwitchCase>();
|
||||
var defaultI = -1;
|
||||
|
||||
@ -151,9 +151,9 @@ public class SwitchStatement extends Statement {
|
||||
continue;
|
||||
}
|
||||
|
||||
ParseRes<Statement> caseRes = ParseRes.first(src, i + n,
|
||||
SwitchStatement::parseDefaultCase,
|
||||
SwitchStatement::parseSwitchCase
|
||||
ParseRes<Node> caseRes = ParseRes.first(src, i + n,
|
||||
SwitchNode::parseDefaultCase,
|
||||
SwitchNode::parseSwitchCase
|
||||
);
|
||||
|
||||
// Parsing::parseStatement
|
||||
@ -176,10 +176,10 @@ public class SwitchStatement extends Statement {
|
||||
else stm.chainError(src.loc(i + n), "Expected a statement, 'case' or 'default'");
|
||||
}
|
||||
|
||||
return ParseRes.res(new SwitchStatement(
|
||||
return ParseRes.res(new SwitchNode(
|
||||
loc, valRes.result, defaultI,
|
||||
cases.toArray(SwitchCase[]::new),
|
||||
statements.toArray(Statement[]::new)
|
||||
statements.toArray(Node[]::new)
|
||||
), n);
|
||||
}
|
||||
}
|
@ -7,10 +7,10 @@ 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.Statement;
|
||||
import me.topchetoeu.jscript.compilation.Node;
|
||||
|
||||
public class ThrowStatement extends Statement {
|
||||
public final Statement value;
|
||||
public class ThrowNode extends Node {
|
||||
public final Node value;
|
||||
|
||||
@Override
|
||||
public void compile(CompileResult target, boolean pollute) {
|
||||
@ -18,12 +18,12 @@ public class ThrowStatement extends Statement {
|
||||
target.add(Instruction.throwInstr()).setLocation(loc());
|
||||
}
|
||||
|
||||
public ThrowStatement(Location loc, Statement value) {
|
||||
public ThrowNode(Location loc, Node value) {
|
||||
super(loc);
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public static ParseRes<ThrowStatement> parse(Source src, int i) {
|
||||
public static ParseRes<ThrowNode> parse(Source src, int i) {
|
||||
var n = Parsing.skipEmpty(src, i);
|
||||
var loc = src.loc(i + n);
|
||||
|
||||
@ -33,7 +33,7 @@ public class ThrowStatement extends Statement {
|
||||
var end = JavaScript.parseStatementEnd(src, i + n);
|
||||
if (end.isSuccess()) {
|
||||
n += end.n;
|
||||
return ParseRes.res(new ThrowStatement(loc, null), n);
|
||||
return ParseRes.res(new ThrowNode(loc, null), n);
|
||||
}
|
||||
|
||||
var val = JavaScript.parseExpression(src, i + n, 0);
|
||||
@ -43,7 +43,7 @@ public class ThrowStatement extends Statement {
|
||||
end = JavaScript.parseStatementEnd(src, i + n);
|
||||
if (end.isSuccess()) {
|
||||
n += end.n;
|
||||
return ParseRes.res(new ThrowStatement(loc, val.result), n);
|
||||
return ParseRes.res(new ThrowNode(loc, val.result), n);
|
||||
}
|
||||
else return end.chainError(src.loc(i + n), "Expected end of statement");
|
||||
}
|
@ -7,13 +7,13 @@ 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.CompoundStatement;
|
||||
import me.topchetoeu.jscript.compilation.Statement;
|
||||
import me.topchetoeu.jscript.compilation.CompoundNode;
|
||||
import me.topchetoeu.jscript.compilation.Node;
|
||||
|
||||
public class TryStatement extends Statement {
|
||||
public final Statement tryBody;
|
||||
public final Statement catchBody;
|
||||
public final Statement finallyBody;
|
||||
public class TryNode extends Node {
|
||||
public final Node tryBody;
|
||||
public final Node catchBody;
|
||||
public final Node finallyBody;
|
||||
public final String name;
|
||||
|
||||
@Override public void declare(CompileResult target) {
|
||||
@ -50,7 +50,7 @@ public class TryStatement extends Statement {
|
||||
if (pollute) target.add(Instruction.pushUndefined());
|
||||
}
|
||||
|
||||
public TryStatement(Location loc, Statement tryBody, Statement catchBody, Statement finallyBody, String name) {
|
||||
public TryNode(Location loc, Node tryBody, Node catchBody, Node finallyBody, String name) {
|
||||
super(loc);
|
||||
this.tryBody = tryBody;
|
||||
this.catchBody = catchBody;
|
||||
@ -58,20 +58,20 @@ public class TryStatement extends Statement {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public static ParseRes<TryStatement> parse(Source src, int i) {
|
||||
public static ParseRes<TryNode> parse(Source src, int i) {
|
||||
var n = Parsing.skipEmpty(src, i);
|
||||
var loc = src.loc(i + n);
|
||||
|
||||
if (!Parsing.isIdentifier(src, i + n, "try")) return ParseRes.failed();
|
||||
n += 3;
|
||||
|
||||
var tryBody = CompoundStatement.parse(src, i + n);
|
||||
var tryBody = CompoundNode.parse(src, i + n);
|
||||
if (!tryBody.isSuccess()) return tryBody.chainError(src.loc(i + n), "Expected a try body");
|
||||
n += tryBody.n;
|
||||
n += Parsing.skipEmpty(src, i + n);
|
||||
|
||||
String name = null;
|
||||
Statement catchBody = null, finallyBody = null;
|
||||
Node catchBody = null, finallyBody = null;
|
||||
|
||||
if (Parsing.isIdentifier(src, i + n, "catch")) {
|
||||
n += 5;
|
||||
@ -88,7 +88,7 @@ public class TryStatement extends Statement {
|
||||
n++;
|
||||
}
|
||||
|
||||
var bodyRes = CompoundStatement.parse(src, i + n);
|
||||
var bodyRes = CompoundNode.parse(src, i + n);
|
||||
if (!bodyRes.isSuccess()) return tryBody.chainError(src.loc(i + n), "Expected a catch body");
|
||||
n += bodyRes.n;
|
||||
n += Parsing.skipEmpty(src, i + n);
|
||||
@ -99,7 +99,7 @@ public class TryStatement extends Statement {
|
||||
if (Parsing.isIdentifier(src, i + n, "finally")) {
|
||||
n += 7;
|
||||
|
||||
var bodyRes = CompoundStatement.parse(src, i + n);
|
||||
var bodyRes = CompoundNode.parse(src, i + n);
|
||||
if (!bodyRes.isSuccess()) return tryBody.chainError(src.loc(i + n), "Expected a finally body");
|
||||
n += bodyRes.n;
|
||||
n += Parsing.skipEmpty(src, i + n);
|
||||
@ -108,6 +108,6 @@ public class TryStatement extends Statement {
|
||||
|
||||
if (finallyBody == null && catchBody == null) ParseRes.error(src.loc(i + n), "Expected catch or finally");
|
||||
|
||||
return ParseRes.res(new TryStatement(loc, tryBody.result, catchBody, finallyBody, name), n);
|
||||
return ParseRes.res(new TryNode(loc, tryBody.result, catchBody, finallyBody, name), n);
|
||||
}
|
||||
}
|
@ -9,10 +9,10 @@ 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.Statement;
|
||||
import me.topchetoeu.jscript.compilation.Node;
|
||||
|
||||
public class WhileStatement extends Statement {
|
||||
public final Statement condition, body;
|
||||
public class WhileNode extends Node {
|
||||
public final Node condition, body;
|
||||
public final String label;
|
||||
|
||||
@Override
|
||||
@ -49,7 +49,7 @@ public class WhileStatement extends Statement {
|
||||
return ParseRes.res(nameRes.result, n);
|
||||
}
|
||||
|
||||
public WhileStatement(Location loc, String label, Statement condition, Statement body) {
|
||||
public WhileNode(Location loc, String label, Node condition, Node body) {
|
||||
super(loc);
|
||||
this.label = label;
|
||||
this.condition = condition;
|
||||
@ -68,11 +68,11 @@ public class WhileStatement extends Statement {
|
||||
}
|
||||
}
|
||||
|
||||
public static ParseRes<WhileStatement> parse(Source src, int i) {
|
||||
public static ParseRes<WhileNode> parse(Source src, int i) {
|
||||
var n = Parsing.skipEmpty(src, i);
|
||||
var loc = src.loc(i + n);
|
||||
|
||||
var labelRes = WhileStatement.parseLabel(src, i + n);
|
||||
var labelRes = WhileNode.parseLabel(src, i + n);
|
||||
n += labelRes.n;
|
||||
n += Parsing.skipEmpty(src, i + n);
|
||||
|
||||
@ -95,6 +95,6 @@ public class WhileStatement extends Statement {
|
||||
if (!res.isSuccess()) return res.chainError(src.loc(i + n), "Expected a while body.");
|
||||
n += res.n;
|
||||
|
||||
return ParseRes.res(new WhileStatement(loc, labelRes.result, condRes.result, res.result), n);
|
||||
return ParseRes.res(new WhileNode(loc, labelRes.result, condRes.result, res.result), n);
|
||||
}
|
||||
}
|
@ -9,10 +9,10 @@ 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.Statement;
|
||||
import me.topchetoeu.jscript.compilation.Node;
|
||||
|
||||
public class ArrayStatement extends Statement {
|
||||
public final Statement[] statements;
|
||||
public class ArrayNode extends Node {
|
||||
public final Node[] statements;
|
||||
|
||||
@Override public boolean pure() {
|
||||
for (var stm : statements) {
|
||||
@ -38,19 +38,19 @@ public class ArrayStatement extends Statement {
|
||||
if (!pollute) target.add(Instruction.discard());
|
||||
}
|
||||
|
||||
public ArrayStatement(Location loc, Statement[] statements) {
|
||||
public ArrayNode(Location loc, Node[] statements) {
|
||||
super(loc);
|
||||
this.statements = statements;
|
||||
}
|
||||
|
||||
public static ParseRes<ArrayStatement> parse(Source src, int i) {
|
||||
public static ParseRes<ArrayNode> 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++;
|
||||
|
||||
var values = new ArrayList<Statement>();
|
||||
var values = new ArrayList<Node>();
|
||||
|
||||
loop: while (true) {
|
||||
n += Parsing.skipEmpty(src, i + n);
|
||||
@ -84,6 +84,6 @@ public class ArrayStatement extends Statement {
|
||||
}
|
||||
}
|
||||
|
||||
return ParseRes.res(new ArrayStatement(loc, values.toArray(Statement[]::new)), n);
|
||||
return ParseRes.res(new ArrayNode(loc, values.toArray(Node[]::new)), n);
|
||||
}
|
||||
}
|
@ -8,13 +8,13 @@ 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.CompoundStatement;
|
||||
import me.topchetoeu.jscript.compilation.CompoundNode;
|
||||
import me.topchetoeu.jscript.compilation.JavaScript;
|
||||
import me.topchetoeu.jscript.compilation.Statement;
|
||||
import me.topchetoeu.jscript.compilation.Node;
|
||||
import me.topchetoeu.jscript.runtime.exceptions.SyntaxException;
|
||||
|
||||
public class FunctionStatement extends Statement {
|
||||
public final CompoundStatement body;
|
||||
public class FunctionNode extends Node {
|
||||
public final CompoundNode body;
|
||||
public final String varName;
|
||||
public final String[] args;
|
||||
public final boolean statement;
|
||||
@ -101,7 +101,7 @@ public class FunctionStatement extends Statement {
|
||||
compile(target, pollute, (String)null, BreakpointType.NONE);
|
||||
}
|
||||
|
||||
public FunctionStatement(Location loc, Location end, String varName, String[] args, boolean statement, CompoundStatement body) {
|
||||
public FunctionNode(Location loc, Location end, String varName, String[] args, boolean statement, CompoundNode body) {
|
||||
super(loc);
|
||||
|
||||
this.end = end;
|
||||
@ -112,16 +112,16 @@ public class FunctionStatement extends Statement {
|
||||
this.body = body;
|
||||
}
|
||||
|
||||
public static void compileWithName(Statement stm, CompileResult target, boolean pollute, String name) {
|
||||
if (stm instanceof FunctionStatement) ((FunctionStatement)stm).compile(target, pollute, name);
|
||||
public static void compileWithName(Node stm, CompileResult target, boolean pollute, String name) {
|
||||
if (stm instanceof FunctionNode) ((FunctionNode)stm).compile(target, pollute, name);
|
||||
else stm.compile(target, pollute);
|
||||
}
|
||||
public static void compileWithName(Statement stm, CompileResult target, boolean pollute, String name, BreakpointType bp) {
|
||||
if (stm instanceof FunctionStatement) ((FunctionStatement)stm).compile(target, pollute, name, bp);
|
||||
public static void compileWithName(Node stm, CompileResult target, boolean pollute, String name, BreakpointType bp) {
|
||||
if (stm instanceof FunctionNode) ((FunctionNode)stm).compile(target, pollute, name, bp);
|
||||
else stm.compile(target, pollute, bp);
|
||||
}
|
||||
|
||||
public static ParseRes<FunctionStatement> parseFunction(Source src, int i, boolean statement) {
|
||||
public static ParseRes<FunctionNode> parseFunction(Source src, int i, boolean statement) {
|
||||
var n = Parsing.skipEmpty(src, i);
|
||||
var loc = src.loc(i + n);
|
||||
|
||||
@ -137,11 +137,11 @@ public class FunctionStatement extends Statement {
|
||||
if (!args.isSuccess()) return args.chainError(src.loc(i + n), "Expected a parameter list");
|
||||
n += args.n;
|
||||
|
||||
var res = CompoundStatement.parse(src, i + n);
|
||||
var res = CompoundNode.parse(src, i + n);
|
||||
if (!res.isSuccess()) return res.chainError(src.loc(i + n), "Expected a compound statement for function.");
|
||||
n += res.n;
|
||||
|
||||
return ParseRes.res(new FunctionStatement(
|
||||
return ParseRes.res(new FunctionNode(
|
||||
loc, src.loc(i + n - 1),
|
||||
nameRes.result, args.result.toArray(String[]::new),
|
||||
statement, res.result
|
@ -3,9 +3,9 @@ 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.Statement;
|
||||
import me.topchetoeu.jscript.compilation.Node;
|
||||
|
||||
public class GlobalThisStatement extends Statement {
|
||||
public class GlobalThisNode extends Node {
|
||||
@Override public boolean pure() { return true; }
|
||||
|
||||
@Override
|
||||
@ -13,7 +13,7 @@ public class GlobalThisStatement extends Statement {
|
||||
if (pollute) target.add(Instruction.loadGlob());
|
||||
}
|
||||
|
||||
public GlobalThisStatement(Location loc) {
|
||||
public GlobalThisNode(Location loc) {
|
||||
super(loc);
|
||||
}
|
||||
}
|
@ -10,26 +10,26 @@ 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.CompoundStatement;
|
||||
import me.topchetoeu.jscript.compilation.CompoundNode;
|
||||
import me.topchetoeu.jscript.compilation.JavaScript;
|
||||
import me.topchetoeu.jscript.compilation.Statement;
|
||||
import me.topchetoeu.jscript.compilation.Node;
|
||||
|
||||
public class ObjectStatement extends Statement {
|
||||
public class ObjectNode extends Node {
|
||||
public static class ObjProp {
|
||||
public final String name;
|
||||
public final String access;
|
||||
public final FunctionStatement func;
|
||||
public final FunctionNode func;
|
||||
|
||||
public ObjProp(String name, String access, FunctionStatement func) {
|
||||
public ObjProp(String name, String access, FunctionNode func) {
|
||||
this.name = name;
|
||||
this.access = access;
|
||||
this.func = func;
|
||||
}
|
||||
}
|
||||
|
||||
public final Map<String, Statement> map;
|
||||
public final Map<String, FunctionStatement> getters;
|
||||
public final Map<String, FunctionStatement> setters;
|
||||
public final Map<String, Node> map;
|
||||
public final Map<String, FunctionNode> getters;
|
||||
public final Map<String, FunctionNode> setters;
|
||||
|
||||
@Override public boolean pure() {
|
||||
for (var el : map.values()) {
|
||||
@ -39,15 +39,14 @@ public class ObjectStatement extends Statement {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void compile(CompileResult target, boolean pollute) {
|
||||
@Override public void compile(CompileResult target, boolean pollute) {
|
||||
target.add(Instruction.loadObj());
|
||||
|
||||
for (var el : map.entrySet()) {
|
||||
target.add(Instruction.dup());
|
||||
target.add(Instruction.pushValue(el.getKey()));
|
||||
var val = el.getValue();
|
||||
FunctionStatement.compileWithName(val, target, true, el.getKey().toString());
|
||||
FunctionNode.compileWithName(val, target, true, el.getKey().toString());
|
||||
target.add(Instruction.storeMember());
|
||||
}
|
||||
|
||||
@ -70,7 +69,7 @@ public class ObjectStatement extends Statement {
|
||||
if (!pollute) target.add(Instruction.discard());
|
||||
}
|
||||
|
||||
public ObjectStatement(Location loc, Map<String, Statement> map, Map<String, FunctionStatement> getters, Map<String, FunctionStatement> setters) {
|
||||
public ObjectNode(Location loc, Map<String, Node> map, Map<String, FunctionNode> getters, Map<String, FunctionNode> setters) {
|
||||
super(loc);
|
||||
this.map = map;
|
||||
this.getters = getters;
|
||||
@ -90,7 +89,7 @@ public class ObjectStatement extends Statement {
|
||||
if (!res.isSuccess()) return res.chainError();
|
||||
return ParseRes.res(res.result.toString(), n);
|
||||
}
|
||||
private static ParseRes<ObjectStatement.ObjProp> parseObjectProp(Source src, int i) {
|
||||
private static ParseRes<ObjectNode.ObjProp> parseObjectProp(Source src, int i) {
|
||||
var n = Parsing.skipEmpty(src, i);
|
||||
var loc = src.loc(i + n);
|
||||
|
||||
@ -107,7 +106,7 @@ public class ObjectStatement extends Statement {
|
||||
if (!params.isSuccess()) return params.chainError(src.loc(i + n), "Expected an argument list");
|
||||
n += params.n;
|
||||
|
||||
var body = CompoundStatement.parse(src, i + 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;
|
||||
|
||||
@ -115,11 +114,11 @@ public class ObjectStatement extends Statement {
|
||||
|
||||
return ParseRes.res(new ObjProp(
|
||||
name.result, access.result,
|
||||
new FunctionStatement(loc, end, access + " " + name.result.toString(), params.result.toArray(String[]::new), false, body.result)
|
||||
new FunctionNode(loc, end, access + " " + name.result.toString(), params.result.toArray(String[]::new), false, body.result)
|
||||
), n);
|
||||
}
|
||||
|
||||
public static ParseRes<ObjectStatement> parse(Source src, int i) {
|
||||
public static ParseRes<ObjectNode> parse(Source src, int i) {
|
||||
var n = Parsing.skipEmpty(src, i);
|
||||
var loc = src.loc(i + n);
|
||||
|
||||
@ -127,13 +126,13 @@ public class ObjectStatement extends Statement {
|
||||
n++;
|
||||
n += Parsing.skipEmpty(src, i + n);
|
||||
|
||||
var values = new LinkedHashMap<String, Statement>();
|
||||
var getters = new LinkedHashMap<String, FunctionStatement>();
|
||||
var setters = new LinkedHashMap<String, FunctionStatement>();
|
||||
var values = new LinkedHashMap<String, Node>();
|
||||
var getters = new LinkedHashMap<String, FunctionNode>();
|
||||
var setters = new LinkedHashMap<String, FunctionNode>();
|
||||
|
||||
if (src.is(i + n, "}")) {
|
||||
n++;
|
||||
return ParseRes.res(new ObjectStatement(loc, values, getters, setters), n);
|
||||
return ParseRes.res(new ObjectNode(loc, values, getters, setters), n);
|
||||
}
|
||||
|
||||
while (true) {
|
||||
@ -180,7 +179,7 @@ public class ObjectStatement extends Statement {
|
||||
else ParseRes.error(src.loc(i + n), "Expected a comma or a closing brace.");
|
||||
}
|
||||
|
||||
return ParseRes.res(new ObjectStatement(loc, values, getters, setters), n);
|
||||
return ParseRes.res(new ObjectNode(loc, values, getters, setters), n);
|
||||
}
|
||||
|
||||
}
|
@ -6,9 +6,9 @@ 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.Statement;
|
||||
import me.topchetoeu.jscript.compilation.Node;
|
||||
|
||||
public class RegexStatement extends Statement {
|
||||
public class RegexNode extends Node {
|
||||
public final String pattern, flags;
|
||||
|
||||
// Not really pure, since a function is called, but can be ignored.
|
||||
@ -21,7 +21,7 @@ public class RegexStatement extends Statement {
|
||||
}
|
||||
|
||||
|
||||
public static ParseRes<RegexStatement> parse(Source src, int i) {
|
||||
public static ParseRes<RegexNode> parse(Source src, int i) {
|
||||
var n = Parsing.skipEmpty(src, i);
|
||||
|
||||
if (!src.is(i + n, '/')) return ParseRes.failed();
|
||||
@ -69,10 +69,10 @@ public class RegexStatement extends Statement {
|
||||
n++;
|
||||
}
|
||||
|
||||
return ParseRes.res(new RegexStatement(loc, source.toString(), flags.toString()), n);
|
||||
return ParseRes.res(new RegexNode(loc, source.toString(), flags.toString()), n);
|
||||
}
|
||||
|
||||
public RegexStatement(Location loc, String pattern, String flags) {
|
||||
public RegexNode(Location loc, String pattern, String flags) {
|
||||
super(loc);
|
||||
this.pattern = pattern;
|
||||
this.flags = flags;
|
@ -6,20 +6,20 @@ 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.AssignableStatement;
|
||||
import me.topchetoeu.jscript.compilation.AssignableNode;
|
||||
import me.topchetoeu.jscript.compilation.CompileResult;
|
||||
import me.topchetoeu.jscript.compilation.JavaScript;
|
||||
import me.topchetoeu.jscript.compilation.Statement;
|
||||
import me.topchetoeu.jscript.compilation.values.operations.VariableAssignStatement;
|
||||
import me.topchetoeu.jscript.compilation.Node;
|
||||
import me.topchetoeu.jscript.compilation.values.operations.VariableAssignNode;
|
||||
|
||||
public class VariableStatement extends Statement implements AssignableStatement {
|
||||
public class VariableNode extends Node implements AssignableNode {
|
||||
public final String name;
|
||||
|
||||
@Override public boolean pure() { return false; }
|
||||
|
||||
@Override
|
||||
public Statement toAssign(Statement val, Operation operation) {
|
||||
return new VariableAssignStatement(loc(), name, val, operation);
|
||||
public Node toAssign(Node val, Operation operation) {
|
||||
return new VariableAssignNode(loc(), name, val, operation);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -29,12 +29,12 @@ public class VariableStatement extends Statement implements AssignableStatement
|
||||
if (!pollute) target.add(Instruction.discard());
|
||||
}
|
||||
|
||||
public VariableStatement(Location loc, String name) {
|
||||
public VariableNode(Location loc, String name) {
|
||||
super(loc);
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public static ParseRes<VariableStatement> parse(Source src, int i) {
|
||||
public static ParseRes<VariableNode> parse(Source src, int i) {
|
||||
var n = Parsing.skipEmpty(src, i);
|
||||
var loc = src.loc(i + n);
|
||||
|
||||
@ -49,6 +49,6 @@ public class VariableStatement extends Statement implements AssignableStatement
|
||||
return ParseRes.error(src.loc(i + n), String.format("Unexpected keyword '%s'.", literal.result));
|
||||
}
|
||||
|
||||
return ParseRes.res(new VariableStatement(loc, literal.result), n);
|
||||
return ParseRes.res(new VariableNode(loc, literal.result), n);
|
||||
}
|
||||
}
|
@ -3,9 +3,9 @@ package me.topchetoeu.jscript.compilation.values.constants;
|
||||
import me.topchetoeu.jscript.common.Instruction;
|
||||
import me.topchetoeu.jscript.common.parsing.Location;
|
||||
import me.topchetoeu.jscript.compilation.CompileResult;
|
||||
import me.topchetoeu.jscript.compilation.Statement;
|
||||
import me.topchetoeu.jscript.compilation.Node;
|
||||
|
||||
public class BoolStatement extends Statement {
|
||||
public class BoolNode extends Node {
|
||||
public final boolean value;
|
||||
|
||||
@Override public boolean pure() { return true; }
|
||||
@ -14,7 +14,7 @@ public class BoolStatement extends Statement {
|
||||
if (pollute) target.add(Instruction.pushValue(value));
|
||||
}
|
||||
|
||||
public BoolStatement(Location loc, boolean value) {
|
||||
public BoolNode(Location loc, boolean value) {
|
||||
super(loc);
|
||||
this.value = value;
|
||||
}
|
@ -1,4 +0,0 @@
|
||||
package me.topchetoeu.jscript.compilation.values.constants;
|
||||
|
||||
public class ConstantStatements {
|
||||
}
|
@ -3,14 +3,14 @@ package me.topchetoeu.jscript.compilation.values.constants;
|
||||
import me.topchetoeu.jscript.common.Instruction;
|
||||
import me.topchetoeu.jscript.common.parsing.Location;
|
||||
import me.topchetoeu.jscript.compilation.CompileResult;
|
||||
import me.topchetoeu.jscript.compilation.Statement;
|
||||
import me.topchetoeu.jscript.compilation.Node;
|
||||
|
||||
public class NullStatement extends Statement {
|
||||
public class NullNode extends Node {
|
||||
@Override public boolean pure() { return true; }
|
||||
|
||||
@Override public void compile(CompileResult target, boolean pollute) {
|
||||
target.add(Instruction.pushNull());
|
||||
}
|
||||
|
||||
public NullStatement(Location loc) { super(loc); }
|
||||
public NullNode(Location loc) { super(loc); }
|
||||
}
|
@ -6,9 +6,9 @@ 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.Statement;
|
||||
import me.topchetoeu.jscript.compilation.Node;
|
||||
|
||||
public class NumberStatement extends Statement {
|
||||
public class NumberNode extends Node {
|
||||
public final double value;
|
||||
|
||||
@Override public boolean pure() { return true; }
|
||||
@ -17,7 +17,7 @@ public class NumberStatement extends Statement {
|
||||
if (pollute) target.add(Instruction.pushValue(value));
|
||||
}
|
||||
|
||||
public NumberStatement(Location loc, double value) {
|
||||
public NumberNode(Location loc, double value) {
|
||||
super(loc);
|
||||
this.value = value;
|
||||
}
|
||||
@ -31,12 +31,12 @@ public class NumberStatement extends Statement {
|
||||
else return a * power(a * a, b / 2);
|
||||
}
|
||||
|
||||
public static ParseRes<NumberStatement> parse(Source src, int i) {
|
||||
public static ParseRes<NumberNode> parse(Source src, int i) {
|
||||
var n = Parsing.skipEmpty(src, i);
|
||||
var loc = src.loc(i + n);
|
||||
|
||||
var res = Parsing.parseNumber(src, i + n, false);
|
||||
if (res.isSuccess()) return ParseRes.res(new NumberStatement(loc, res.result), n + res.n);
|
||||
if (res.isSuccess()) return ParseRes.res(new NumberNode(loc, res.result), n + res.n);
|
||||
else return res.chainError();
|
||||
}
|
||||
}
|
@ -6,9 +6,9 @@ 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.Statement;
|
||||
import me.topchetoeu.jscript.compilation.Node;
|
||||
|
||||
public class StringStatement extends Statement {
|
||||
public class StringNode extends Node {
|
||||
public final String value;
|
||||
|
||||
@Override public boolean pure() { return true; }
|
||||
@ -17,17 +17,17 @@ public class StringStatement extends Statement {
|
||||
if (pollute) target.add(Instruction.pushValue(value));
|
||||
}
|
||||
|
||||
public StringStatement(Location loc, String value) {
|
||||
public StringNode(Location loc, String value) {
|
||||
super(loc);
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public static ParseRes<StringStatement> parse(Source src, int i) {
|
||||
public static ParseRes<StringNode> parse(Source src, int i) {
|
||||
var n = Parsing.skipEmpty(src, i);
|
||||
var loc = src.loc(i + n);
|
||||
|
||||
var res = Parsing.parseString(src, i + n);
|
||||
if (res.isSuccess()) return ParseRes.res(new StringStatement(loc, res.result), n + res.n);
|
||||
if (res.isSuccess()) return ParseRes.res(new StringNode(loc, res.result), n + res.n);
|
||||
else return res.chainError();
|
||||
}
|
||||
}
|
@ -12,55 +12,55 @@ 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.Statement;
|
||||
import me.topchetoeu.jscript.compilation.values.ArrayStatement;
|
||||
import me.topchetoeu.jscript.compilation.values.ObjectStatement;
|
||||
import me.topchetoeu.jscript.compilation.values.VariableStatement;
|
||||
import me.topchetoeu.jscript.compilation.values.constants.BoolStatement;
|
||||
import me.topchetoeu.jscript.compilation.values.constants.NumberStatement;
|
||||
import me.topchetoeu.jscript.compilation.values.constants.StringStatement;
|
||||
import me.topchetoeu.jscript.compilation.Node;
|
||||
import me.topchetoeu.jscript.compilation.values.ArrayNode;
|
||||
import me.topchetoeu.jscript.compilation.values.ObjectNode;
|
||||
import me.topchetoeu.jscript.compilation.values.VariableNode;
|
||||
import me.topchetoeu.jscript.compilation.values.constants.BoolNode;
|
||||
import me.topchetoeu.jscript.compilation.values.constants.NumberNode;
|
||||
import me.topchetoeu.jscript.compilation.values.constants.StringNode;
|
||||
|
||||
public class CallStatement extends Statement {
|
||||
public class CallNode extends Node {
|
||||
public static boolean ATTACH_NAME = true;
|
||||
|
||||
public final Statement func;
|
||||
public final Statement[] args;
|
||||
public final Node func;
|
||||
public final Node[] args;
|
||||
public final boolean isNew;
|
||||
|
||||
private String generateName(Statement func, Statement index) {
|
||||
private String generateName(Node func, Node index) {
|
||||
String res = "(intermediate value)";
|
||||
boolean shouldParen = false;
|
||||
|
||||
if (func instanceof ObjectStatement) {
|
||||
var obj = (ObjectStatement)func;
|
||||
if (func instanceof ObjectNode) {
|
||||
var obj = (ObjectNode)func;
|
||||
|
||||
shouldParen = true;
|
||||
|
||||
if (obj.getters.size() > 0 || obj.setters.size() > 0 || obj.map.size() > 0) res = "{}";
|
||||
else res = "{(intermediate value)}";
|
||||
}
|
||||
else if (func instanceof StringStatement) {
|
||||
res = JSON.stringify(JSONElement.string(((StringStatement)func).value));
|
||||
else if (func instanceof StringNode) {
|
||||
res = JSON.stringify(JSONElement.string(((StringNode)func).value));
|
||||
}
|
||||
else if (func instanceof NumberStatement) {
|
||||
res = JSON.stringify(JSONElement.number(((NumberStatement)func).value));
|
||||
else if (func instanceof NumberNode) {
|
||||
res = JSON.stringify(JSONElement.number(((NumberNode)func).value));
|
||||
}
|
||||
else if (func instanceof BoolStatement) {
|
||||
res = ((BoolStatement)func).value ? "true" : "false";
|
||||
else if (func instanceof BoolNode) {
|
||||
res = ((BoolNode)func).value ? "true" : "false";
|
||||
}
|
||||
else if (func instanceof VariableStatement) {
|
||||
res = ((VariableStatement)func).name;
|
||||
else if (func instanceof VariableNode) {
|
||||
res = ((VariableNode)func).name;
|
||||
}
|
||||
else if (func instanceof VariableIndexStatement) {
|
||||
var i = ((VariableIndexStatement)func).index;
|
||||
else if (func instanceof VariableIndexNode) {
|
||||
var i = ((VariableIndexNode)func).index;
|
||||
|
||||
if (i == 0) res = "this";
|
||||
else if (i == 1) res = "arguments";
|
||||
}
|
||||
else if (func instanceof ArrayStatement) {
|
||||
else if (func instanceof ArrayNode) {
|
||||
var els = new ArrayList<String>();
|
||||
|
||||
for (var el : ((ArrayStatement)func).statements) {
|
||||
for (var el : ((ArrayNode)func).statements) {
|
||||
if (el != null) els.add(generateName(el, null));
|
||||
else els.add("(intermediate value)");
|
||||
}
|
||||
@ -72,8 +72,8 @@ public class CallStatement extends Statement {
|
||||
|
||||
if (shouldParen) res = "(" + res + ")";
|
||||
|
||||
if (index instanceof StringStatement) {
|
||||
var val = ((StringStatement)index).value;
|
||||
if (index instanceof StringNode) {
|
||||
var val = ((StringNode)index).value;
|
||||
var bracket = JSON.stringify(JSONElement.string(val));
|
||||
|
||||
if (!bracket.substring(1, bracket.length() - 1).equals(val)) return res + "[" + bracket + "]";
|
||||
@ -86,9 +86,9 @@ public class CallStatement extends Statement {
|
||||
}
|
||||
|
||||
@Override public void compile(CompileResult target, boolean pollute, BreakpointType type) {
|
||||
if (!isNew && func instanceof IndexStatement) {
|
||||
var obj = ((IndexStatement)func).object;
|
||||
var index = ((IndexStatement)func).index;
|
||||
if (!isNew && func instanceof IndexNode) {
|
||||
var obj = ((IndexNode)func).object;
|
||||
var index = ((IndexNode)func).index;
|
||||
String name = "";
|
||||
|
||||
obj.compile(target, true);
|
||||
@ -116,14 +116,14 @@ public class CallStatement extends Statement {
|
||||
compile(target, pollute, BreakpointType.STEP_IN);
|
||||
}
|
||||
|
||||
public CallStatement(Location loc, boolean isNew, Statement func, Statement ...args) {
|
||||
public CallNode(Location loc, boolean isNew, Node func, Node ...args) {
|
||||
super(loc);
|
||||
this.isNew = isNew;
|
||||
this.func = func;
|
||||
this.args = args;
|
||||
}
|
||||
|
||||
public static ParseRes<CallStatement> parseCall(Source src, int i, Statement prev, int precedence) {
|
||||
public static ParseRes<CallNode> parseCall(Source src, int i, Node prev, int precedence) {
|
||||
if (precedence > 17) return ParseRes.failed();
|
||||
|
||||
var n = Parsing.skipEmpty(src, i);
|
||||
@ -132,7 +132,7 @@ public class CallStatement extends Statement {
|
||||
if (!src.is(i + n, "(")) return ParseRes.failed();
|
||||
n++;
|
||||
|
||||
var args = new ArrayList<Statement>();
|
||||
var args = new ArrayList<Node>();
|
||||
boolean prevArg = false;
|
||||
|
||||
while (true) {
|
||||
@ -157,9 +157,9 @@ public class CallStatement extends Statement {
|
||||
else return ParseRes.error(src.loc(i + n), "Expected an expression or a closing paren");
|
||||
}
|
||||
|
||||
return ParseRes.res(new CallStatement(loc, false, prev, args.toArray(Statement[]::new)), n);
|
||||
return ParseRes.res(new CallNode(loc, false, prev, args.toArray(Node[]::new)), n);
|
||||
}
|
||||
public static ParseRes<CallStatement> parseNew(Source src, int i) {
|
||||
public static ParseRes<CallNode> parseNew(Source src, int i) {
|
||||
var n = Parsing.skipEmpty(src, i);
|
||||
var loc = src.loc(i + n);
|
||||
|
||||
@ -170,11 +170,11 @@ public class CallStatement extends Statement {
|
||||
if (!valRes.isSuccess()) return valRes.chainError(src.loc(i + n), "Expected a value after 'new' keyword.");
|
||||
n += valRes.n;
|
||||
|
||||
var callRes = CallStatement.parseCall(src, i + n, valRes.result, 0);
|
||||
if (callRes.isFailed()) return ParseRes.res(new CallStatement(loc, true, valRes.result), n);
|
||||
var callRes = CallNode.parseCall(src, i + n, valRes.result, 0);
|
||||
if (callRes.isFailed()) return ParseRes.res(new CallNode(loc, true, valRes.result), n);
|
||||
if (callRes.isError()) return callRes.chainError();
|
||||
n += callRes.n;
|
||||
|
||||
return ParseRes.res(new CallStatement(loc, true, callRes.result.func, callRes.result.args), n);
|
||||
return ParseRes.res(new CallNode(loc, true, callRes.result.func, callRes.result.args), n);
|
||||
}
|
||||
}
|
@ -6,19 +6,19 @@ 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.AssignableStatement;
|
||||
import me.topchetoeu.jscript.compilation.AssignableNode;
|
||||
import me.topchetoeu.jscript.compilation.CompileResult;
|
||||
import me.topchetoeu.jscript.compilation.JavaScript;
|
||||
import me.topchetoeu.jscript.compilation.Statement;
|
||||
import me.topchetoeu.jscript.compilation.values.constants.NumberStatement;
|
||||
import me.topchetoeu.jscript.compilation.Node;
|
||||
import me.topchetoeu.jscript.compilation.values.constants.NumberNode;
|
||||
|
||||
public class ChangeStatement extends Statement {
|
||||
public final AssignableStatement value;
|
||||
public class ChangeNode extends Node {
|
||||
public final AssignableNode value;
|
||||
public final double addAmount;
|
||||
public final boolean postfix;
|
||||
|
||||
@Override public void compile(CompileResult target, boolean pollute) {
|
||||
value.toAssign(new NumberStatement(loc(), -addAmount), Operation.SUBTRACT).compile(target, true);
|
||||
value.toAssign(new NumberNode(loc(), -addAmount), Operation.SUBTRACT).compile(target, true);
|
||||
if (!pollute) target.add(Instruction.discard());
|
||||
else if (postfix) {
|
||||
target.add(Instruction.pushValue(addAmount));
|
||||
@ -26,14 +26,14 @@ public class ChangeStatement extends Statement {
|
||||
}
|
||||
}
|
||||
|
||||
public ChangeStatement(Location loc, AssignableStatement value, double addAmount, boolean postfix) {
|
||||
public ChangeNode(Location loc, AssignableNode value, double addAmount, boolean postfix) {
|
||||
super(loc);
|
||||
this.value = value;
|
||||
this.addAmount = addAmount;
|
||||
this.postfix = postfix;
|
||||
}
|
||||
|
||||
public static ParseRes<ChangeStatement> parsePrefixIncrease(Source src, int i) {
|
||||
public static ParseRes<ChangeNode> parsePrefixIncrease(Source src, int i) {
|
||||
var n = Parsing.skipEmpty(src, i);
|
||||
var loc = src.loc(i + n);
|
||||
|
||||
@ -42,11 +42,11 @@ public class ChangeStatement extends Statement {
|
||||
|
||||
var res = JavaScript.parseExpression(src, i + n, 15);
|
||||
if (!res.isSuccess()) return res.chainError(src.loc(i + n), "Expected assignable value after prefix operator.");
|
||||
else if (!(res.result instanceof AssignableStatement)) return ParseRes.error(src.loc(i + n), "Expected assignable value after prefix operator.");
|
||||
else if (!(res.result instanceof AssignableNode)) return ParseRes.error(src.loc(i + n), "Expected assignable value after prefix operator.");
|
||||
|
||||
return ParseRes.res(new ChangeStatement(loc, (AssignableStatement)res.result, 1, false), n + res.n);
|
||||
return ParseRes.res(new ChangeNode(loc, (AssignableNode)res.result, 1, false), n + res.n);
|
||||
}
|
||||
public static ParseRes<ChangeStatement> parsePrefixDecrease(Source src, int i) {
|
||||
public static ParseRes<ChangeNode> parsePrefixDecrease(Source src, int i) {
|
||||
var n = Parsing.skipEmpty(src, i);
|
||||
var loc = src.loc(i + n);
|
||||
|
||||
@ -55,33 +55,33 @@ public class ChangeStatement extends Statement {
|
||||
|
||||
var res = JavaScript.parseExpression(src, i + n, 15);
|
||||
if (!res.isSuccess()) return res.chainError(src.loc(i + n), "Expected assignable value after prefix operator.");
|
||||
else if (!(res.result instanceof AssignableStatement)) return ParseRes.error(src.loc(i + n), "Expected assignable value after prefix operator.");
|
||||
else if (!(res.result instanceof AssignableNode)) return ParseRes.error(src.loc(i + n), "Expected assignable value after prefix operator.");
|
||||
|
||||
return ParseRes.res(new ChangeStatement(loc, (AssignableStatement)res.result, -1, false), n + res.n);
|
||||
return ParseRes.res(new ChangeNode(loc, (AssignableNode)res.result, -1, false), n + res.n);
|
||||
}
|
||||
|
||||
public static ParseRes<ChangeStatement> parsePostfixIncrease(Source src, int i, Statement prev, int precedence) {
|
||||
public static ParseRes<ChangeNode> parsePostfixIncrease(Source src, int i, Node prev, int precedence) {
|
||||
if (precedence > 15) return ParseRes.failed();
|
||||
|
||||
var n = Parsing.skipEmpty(src, i);
|
||||
var loc = src.loc(i + n);
|
||||
|
||||
if (!src.is(i + n, "++")) return ParseRes.failed();
|
||||
if (!(prev instanceof AssignableStatement)) return ParseRes.error(src.loc(i + n), "Expected assignable value before suffix operator.");
|
||||
if (!(prev instanceof AssignableNode)) return ParseRes.error(src.loc(i + n), "Expected assignable value before suffix operator.");
|
||||
n += 2;
|
||||
|
||||
return ParseRes.res(new ChangeStatement(loc, (AssignableStatement)prev, 1, true), n);
|
||||
return ParseRes.res(new ChangeNode(loc, (AssignableNode)prev, 1, true), n);
|
||||
}
|
||||
public static ParseRes<ChangeStatement> parsePostfixDecrease(Source src, int i, Statement prev, int precedence) {
|
||||
public static ParseRes<ChangeNode> parsePostfixDecrease(Source src, int i, Node prev, int precedence) {
|
||||
if (precedence > 15) return ParseRes.failed();
|
||||
|
||||
var n = Parsing.skipEmpty(src, i);
|
||||
var loc = src.loc(i + n);
|
||||
|
||||
if (!src.is(i + n, "--")) return ParseRes.failed();
|
||||
if (!(prev instanceof AssignableStatement)) return ParseRes.error(src.loc(i + n), "Expected assignable value before suffix operator.");
|
||||
if (!(prev instanceof AssignableNode)) return ParseRes.error(src.loc(i + n), "Expected assignable value before suffix operator.");
|
||||
n += 2;
|
||||
|
||||
return ParseRes.res(new ChangeStatement(loc, (AssignableStatement)prev, -1, true), n);
|
||||
return ParseRes.res(new ChangeNode(loc, (AssignableNode)prev, -1, true), n);
|
||||
}
|
||||
}
|
@ -7,10 +7,10 @@ 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.Statement;
|
||||
import me.topchetoeu.jscript.compilation.Node;
|
||||
|
||||
public class DiscardStatement extends Statement {
|
||||
public final Statement value;
|
||||
public class DiscardNode extends Node {
|
||||
public final Node value;
|
||||
|
||||
@Override public boolean pure() { return value.pure(); }
|
||||
|
||||
@ -19,12 +19,12 @@ public class DiscardStatement extends Statement {
|
||||
if (pollute) target.add(Instruction.pushUndefined());
|
||||
}
|
||||
|
||||
public DiscardStatement(Location loc, Statement val) {
|
||||
public DiscardNode(Location loc, Node val) {
|
||||
super(loc);
|
||||
this.value = val;
|
||||
}
|
||||
|
||||
public static ParseRes<DiscardStatement> parse(Source src, int i) {
|
||||
public static ParseRes<DiscardNode> parse(Source src, int i) {
|
||||
var n = Parsing.skipEmpty(src, i);
|
||||
var loc = src.loc(i + n);
|
||||
|
||||
@ -35,6 +35,6 @@ public class DiscardStatement extends Statement {
|
||||
if (!valRes.isSuccess()) return valRes.chainError(src.loc(i + n), "Expected a value after 'void' keyword.");
|
||||
n += valRes.n;
|
||||
|
||||
return ParseRes.res(new DiscardStatement(loc, valRes.result), n);
|
||||
return ParseRes.res(new DiscardNode(loc, valRes.result), n);
|
||||
}
|
||||
}
|
@ -5,12 +5,12 @@ import me.topchetoeu.jscript.common.Operation;
|
||||
import me.topchetoeu.jscript.common.Instruction.BreakpointType;
|
||||
import me.topchetoeu.jscript.common.parsing.Location;
|
||||
import me.topchetoeu.jscript.compilation.CompileResult;
|
||||
import me.topchetoeu.jscript.compilation.Statement;
|
||||
import me.topchetoeu.jscript.compilation.Node;
|
||||
|
||||
public class IndexAssignStatement extends Statement {
|
||||
public final Statement object;
|
||||
public final Statement index;
|
||||
public final Statement value;
|
||||
public class IndexAssignNode extends Node {
|
||||
public final Node object;
|
||||
public final Node index;
|
||||
public final Node value;
|
||||
public final Operation operation;
|
||||
|
||||
@Override
|
||||
@ -35,7 +35,7 @@ public class IndexAssignStatement extends Statement {
|
||||
}
|
||||
}
|
||||
|
||||
public IndexAssignStatement(Location loc, Statement object, Statement index, Statement value, Operation operation) {
|
||||
public IndexAssignNode(Location loc, Node object, Node index, Node value, Operation operation) {
|
||||
super(loc);
|
||||
this.object = object;
|
||||
this.index = index;
|
@ -7,19 +7,19 @@ 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.AssignableStatement;
|
||||
import me.topchetoeu.jscript.compilation.AssignableNode;
|
||||
import me.topchetoeu.jscript.compilation.CompileResult;
|
||||
import me.topchetoeu.jscript.compilation.JavaScript;
|
||||
import me.topchetoeu.jscript.compilation.Statement;
|
||||
import me.topchetoeu.jscript.compilation.values.constants.StringStatement;
|
||||
import me.topchetoeu.jscript.compilation.Node;
|
||||
import me.topchetoeu.jscript.compilation.values.constants.StringNode;
|
||||
|
||||
public class IndexStatement extends Statement implements AssignableStatement {
|
||||
public final Statement object;
|
||||
public final Statement index;
|
||||
public class IndexNode extends Node implements AssignableNode {
|
||||
public final Node object;
|
||||
public final Node index;
|
||||
|
||||
@Override
|
||||
public Statement toAssign(Statement val, Operation operation) {
|
||||
return new IndexAssignStatement(loc(), object, index, val, operation);
|
||||
public Node toAssign(Node val, Operation operation) {
|
||||
return new IndexAssignNode(loc(), object, index, val, operation);
|
||||
}
|
||||
public void compile(CompileResult target, boolean dupObj, boolean pollute) {
|
||||
object.compile(target, true);
|
||||
@ -34,13 +34,13 @@ public class IndexStatement extends Statement implements AssignableStatement {
|
||||
compile(target, false, pollute);
|
||||
}
|
||||
|
||||
public IndexStatement(Location loc, Statement object, Statement index) {
|
||||
public IndexNode(Location loc, Node object, Node index) {
|
||||
super(loc);
|
||||
this.object = object;
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
public static ParseRes<IndexStatement> parseIndex(Source src, int i, Statement prev, int precedence) {
|
||||
public static ParseRes<IndexNode> parseIndex(Source src, int i, Node prev, int precedence) {
|
||||
if (precedence > 18) return ParseRes.failed();
|
||||
|
||||
var n = Parsing.skipEmpty(src, i);
|
||||
@ -57,9 +57,9 @@ public class IndexStatement extends Statement implements AssignableStatement {
|
||||
if (!src.is(i + n, "]")) return ParseRes.error(src.loc(i + n), "Expected a closing bracket");
|
||||
n++;
|
||||
|
||||
return ParseRes.res(new IndexStatement(loc, prev, valRes.result), n);
|
||||
return ParseRes.res(new IndexNode(loc, prev, valRes.result), n);
|
||||
}
|
||||
public static ParseRes<IndexStatement> parseMember(Source src, int i, Statement prev, int precedence) {
|
||||
public static ParseRes<IndexNode> parseMember(Source src, int i, Node prev, int precedence) {
|
||||
if (precedence > 18) return ParseRes.failed();
|
||||
|
||||
var n = Parsing.skipEmpty(src, i);
|
||||
@ -72,6 +72,6 @@ public class IndexStatement extends Statement implements AssignableStatement {
|
||||
if (!literal.isSuccess()) return literal.chainError(src.loc(i + n), "Expected an identifier after member access.");
|
||||
n += literal.n;
|
||||
|
||||
return ParseRes.res(new IndexStatement(loc, prev, new StringStatement(loc, literal.result)), n);
|
||||
return ParseRes.res(new IndexNode(loc, prev, new StringNode(loc, literal.result)), n);
|
||||
}
|
||||
}
|
@ -7,10 +7,10 @@ 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.Statement;
|
||||
import me.topchetoeu.jscript.compilation.Node;
|
||||
|
||||
public class LazyAndStatement extends Statement {
|
||||
public final Statement first, second;
|
||||
public class LazyAndNode extends Node {
|
||||
public final Node first, second;
|
||||
|
||||
@Override public boolean pure() { return first.pure() && second.pure(); }
|
||||
|
||||
@ -24,14 +24,14 @@ public class LazyAndStatement extends Statement {
|
||||
target.set(start, Instruction.jmpIfNot(target.size() - start));
|
||||
}
|
||||
|
||||
public LazyAndStatement(Location loc, Statement first, Statement second) {
|
||||
public LazyAndNode(Location loc, Node first, Node second) {
|
||||
super(loc);
|
||||
this.first = first;
|
||||
this.second = second;
|
||||
}
|
||||
|
||||
|
||||
public static ParseRes<LazyAndStatement> parse(Source src, int i, Statement prev, int precedence) {
|
||||
public static ParseRes<LazyAndNode> parse(Source src, int i, Node prev, int precedence) {
|
||||
if (precedence < 4) return ParseRes.failed();
|
||||
var n = Parsing.skipEmpty(src, i);
|
||||
|
||||
@ -43,6 +43,6 @@ public class LazyAndStatement extends Statement {
|
||||
if (!res.isSuccess()) return res.chainError(src.loc(i + n), "Expected a value after the '&&' operator.");
|
||||
n += res.n;
|
||||
|
||||
return ParseRes.res(new LazyAndStatement(loc, prev, res.result), n);
|
||||
return ParseRes.res(new LazyAndNode(loc, prev, res.result), n);
|
||||
}
|
||||
}
|
@ -7,10 +7,10 @@ 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.Statement;
|
||||
import me.topchetoeu.jscript.compilation.Node;
|
||||
|
||||
public class LazyOrStatement extends Statement {
|
||||
public final Statement first, second;
|
||||
public class LazyOrNode extends Node {
|
||||
public final Node first, second;
|
||||
|
||||
@Override public boolean pure() { return first.pure() && second.pure(); }
|
||||
|
||||
@ -24,14 +24,14 @@ public class LazyOrStatement extends Statement {
|
||||
target.set(start, Instruction.jmpIf(target.size() - start));
|
||||
}
|
||||
|
||||
public LazyOrStatement(Location loc, Statement first, Statement second) {
|
||||
public LazyOrNode(Location loc, Node first, Node second) {
|
||||
super(loc);
|
||||
this.first = first;
|
||||
this.second = second;
|
||||
}
|
||||
|
||||
|
||||
public static ParseRes<LazyOrStatement> parse(Source src, int i, Statement prev, int precedence) {
|
||||
public static ParseRes<LazyOrNode> parse(Source src, int i, Node prev, int precedence) {
|
||||
if (precedence < 3) return ParseRes.failed();
|
||||
var n = Parsing.skipEmpty(src, i);
|
||||
|
||||
@ -43,6 +43,6 @@ public class LazyOrStatement extends Statement {
|
||||
if (!res.isSuccess()) return res.chainError(src.loc(i + n), "Expected a value after the '||' operator.");
|
||||
n += res.n;
|
||||
|
||||
return ParseRes.res(new LazyOrStatement(loc, prev, res.result), n);
|
||||
return ParseRes.res(new LazyOrNode(loc, prev, res.result), n);
|
||||
}
|
||||
}
|
@ -11,16 +11,16 @@ 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.AssignableStatement;
|
||||
import me.topchetoeu.jscript.compilation.AssignableNode;
|
||||
import me.topchetoeu.jscript.compilation.CompileResult;
|
||||
import me.topchetoeu.jscript.compilation.JavaScript;
|
||||
import me.topchetoeu.jscript.compilation.Statement;
|
||||
import me.topchetoeu.jscript.compilation.Node;
|
||||
|
||||
public class OperationStatement extends Statement {
|
||||
public class OperationNode extends Node {
|
||||
private static interface OperatorFactory {
|
||||
String token();
|
||||
int precedence();
|
||||
ParseRes<Statement> construct(Source src, int i, Statement prev);
|
||||
ParseRes<Node> construct(Source src, int i, Node prev);
|
||||
}
|
||||
|
||||
private static class NormalOperatorFactory implements OperatorFactory {
|
||||
@ -30,12 +30,12 @@ public class OperationStatement extends Statement {
|
||||
|
||||
@Override public int precedence() { return precedence; }
|
||||
@Override public String token() { return token; }
|
||||
@Override public ParseRes<Statement> construct(Source src, int i, Statement prev) {
|
||||
@Override public ParseRes<Node> construct(Source src, int i, Node prev) {
|
||||
var loc = src.loc(i);
|
||||
|
||||
var other = JavaScript.parseExpression(src, i, precedence + 1);
|
||||
if (!other.isSuccess()) return other.chainError(src.loc(i + other.n), String.format("Expected a value after '%s'", token));
|
||||
return ParseRes.res(new OperationStatement(loc, operation, prev, (Statement)other.result), other.n);
|
||||
return ParseRes.res(new OperationNode(loc, operation, prev, (Node)other.result), other.n);
|
||||
}
|
||||
|
||||
public NormalOperatorFactory(String token, int precedence, Operation operation) {
|
||||
@ -51,14 +51,14 @@ public class OperationStatement extends Statement {
|
||||
|
||||
@Override public int precedence() { return precedence; }
|
||||
@Override public String token() { return token; }
|
||||
@Override public ParseRes<Statement> construct(Source src, int i, Statement prev) {
|
||||
@Override public ParseRes<Node> construct(Source src, int i, Node prev) {
|
||||
var loc = src.loc(i);
|
||||
|
||||
if (!(prev instanceof AssignableStatement)) return ParseRes.error(loc, String.format("Expected an assignable expression before '%s'", token));
|
||||
if (!(prev instanceof AssignableNode)) return ParseRes.error(loc, String.format("Expected an assignable expression before '%s'", token));
|
||||
|
||||
var other = JavaScript.parseExpression(src, i, precedence);
|
||||
if (!other.isSuccess()) return other.chainError(src.loc(i + other.n), String.format("Expected a value after '%s'", token));
|
||||
return ParseRes.res(((AssignableStatement)prev).toAssign(other.result, operation), other.n);
|
||||
return ParseRes.res(((AssignableNode)prev).toAssign(other.result, operation), other.n);
|
||||
}
|
||||
|
||||
public AssignmentOperatorFactory(String token, int precedence, Operation operation) {
|
||||
@ -70,27 +70,27 @@ public class OperationStatement extends Statement {
|
||||
private static class LazyAndFactory implements OperatorFactory {
|
||||
@Override public int precedence() { return 4; }
|
||||
@Override public String token() { return "&&"; }
|
||||
@Override public ParseRes<Statement> construct(Source src, int i, Statement prev) {
|
||||
@Override public ParseRes<Node> construct(Source src, int i, Node prev) {
|
||||
var loc = src.loc(i);
|
||||
|
||||
var other = JavaScript.parseExpression(src, i, 5);
|
||||
if (!other.isSuccess()) return other.chainError(src.loc(i + other.n), "Expected a value after '&&'");
|
||||
return ParseRes.res(new LazyAndStatement(loc, prev, (Statement)other.result), other.n);
|
||||
return ParseRes.res(new LazyAndNode(loc, prev, (Node)other.result), other.n);
|
||||
}
|
||||
}
|
||||
private static class LazyOrFactory implements OperatorFactory {
|
||||
@Override public int precedence() { return 5; }
|
||||
@Override public String token() { return "||"; }
|
||||
@Override public ParseRes<Statement> construct(Source src, int i, Statement prev) {
|
||||
@Override public ParseRes<Node> construct(Source src, int i, Node prev) {
|
||||
var loc = src.loc(i);
|
||||
|
||||
var other = JavaScript.parseExpression(src, i, 6);
|
||||
if (!other.isSuccess()) return other.chainError(src.loc(i + other.n), "Expected a value after '||'");
|
||||
return ParseRes.res(new LazyOrStatement(loc, prev, (Statement)other.result), other.n);
|
||||
return ParseRes.res(new LazyOrNode(loc, prev, (Node)other.result), other.n);
|
||||
}
|
||||
}
|
||||
|
||||
public final Statement[] args;
|
||||
public final Node[] args;
|
||||
public final Operation operation;
|
||||
|
||||
@Override public boolean pure() {
|
||||
@ -110,7 +110,7 @@ public class OperationStatement extends Statement {
|
||||
else target.add(Instruction.discard());
|
||||
}
|
||||
|
||||
public OperationStatement(Location loc, Operation operation, Statement ...args) {
|
||||
public OperationNode(Location loc, Operation operation, Node ...args) {
|
||||
super(loc);
|
||||
this.operation = operation;
|
||||
this.args = args;
|
||||
@ -156,7 +156,7 @@ public class OperationStatement extends Statement {
|
||||
|
||||
private static final List<String> operatorsByLength = factories.keySet().stream().sorted((a, b) -> -a.compareTo(b)).collect(Collectors.toList());
|
||||
|
||||
public static ParseRes<OperationStatement> parsePrefix(Source src, int i) {
|
||||
public static ParseRes<OperationNode> parsePrefix(Source src, int i) {
|
||||
var n = Parsing.skipEmpty(src, i);
|
||||
var loc = src.loc(i + n);
|
||||
|
||||
@ -173,10 +173,10 @@ public class OperationStatement extends Statement {
|
||||
|
||||
var res = JavaScript.parseExpression(src, i + n, 14);
|
||||
|
||||
if (res.isSuccess()) return ParseRes.res(new OperationStatement(loc, operation, res.result), n + res.n);
|
||||
if (res.isSuccess()) return ParseRes.res(new OperationNode(loc, operation, res.result), n + res.n);
|
||||
else return res.chainError(src.loc(i + n), String.format("Expected a value after the unary operator '%s'.", op));
|
||||
}
|
||||
public static ParseRes<OperationStatement> parseInstanceof(Source src, int i, Statement prev, int precedence) {
|
||||
public static ParseRes<OperationNode> parseInstanceof(Source src, int i, Node prev, int precedence) {
|
||||
if (precedence > 9) return ParseRes.failed();
|
||||
|
||||
var n = Parsing.skipEmpty(src, i);
|
||||
@ -190,9 +190,9 @@ public class OperationStatement extends Statement {
|
||||
if (!valRes.isSuccess()) return valRes.chainError(src.loc(i + n), "Expected a value after 'instanceof'.");
|
||||
n += valRes.n;
|
||||
|
||||
return ParseRes.res(new OperationStatement(loc, Operation.INSTANCEOF, prev, valRes.result), n);
|
||||
return ParseRes.res(new OperationNode(loc, Operation.INSTANCEOF, prev, valRes.result), n);
|
||||
}
|
||||
public static ParseRes<OperationStatement> parseIn(Source src, int i, Statement prev, int precedence) {
|
||||
public static ParseRes<OperationNode> parseIn(Source src, int i, Node prev, int precedence) {
|
||||
if (precedence > 9) return ParseRes.failed();
|
||||
|
||||
var n = Parsing.skipEmpty(src, i);
|
||||
@ -206,9 +206,9 @@ public class OperationStatement extends Statement {
|
||||
if (!valRes.isSuccess()) return valRes.chainError(src.loc(i + n), "Expected a value after 'in'.");
|
||||
n += valRes.n;
|
||||
|
||||
return ParseRes.res(new OperationStatement(loc, Operation.IN, valRes.result, prev), n);
|
||||
return ParseRes.res(new OperationNode(loc, Operation.IN, valRes.result, prev), n);
|
||||
}
|
||||
public static ParseRes<? extends Statement> parseOperator(Source src, int i, Statement prev, int precedence) {
|
||||
public static ParseRes<? extends Node> parseOperator(Source src, int i, Node prev, int precedence) {
|
||||
var n = Parsing.skipEmpty(src, i);
|
||||
|
||||
for (var token : operatorsByLength) {
|
@ -7,11 +7,11 @@ 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.Statement;
|
||||
import me.topchetoeu.jscript.compilation.values.VariableStatement;
|
||||
import me.topchetoeu.jscript.compilation.Node;
|
||||
import me.topchetoeu.jscript.compilation.values.VariableNode;
|
||||
|
||||
public class TypeofStatement extends Statement {
|
||||
public final Statement value;
|
||||
public class TypeofNode extends Node {
|
||||
public final Node value;
|
||||
|
||||
// Not really pure, since a variable from the global scope could be accessed,
|
||||
// which could lead to code execution, that would get omitted
|
||||
@ -19,8 +19,8 @@ public class TypeofStatement extends Statement {
|
||||
|
||||
@Override
|
||||
public void compile(CompileResult target, boolean pollute) {
|
||||
if (value instanceof VariableStatement) {
|
||||
var i = target.scope.getKey(((VariableStatement)value).name);
|
||||
if (value instanceof VariableNode) {
|
||||
var i = target.scope.getKey(((VariableNode)value).name);
|
||||
if (i instanceof String) {
|
||||
target.add(Instruction.typeof((String)i));
|
||||
return;
|
||||
@ -30,12 +30,12 @@ public class TypeofStatement extends Statement {
|
||||
target.add(Instruction.typeof());
|
||||
}
|
||||
|
||||
public TypeofStatement(Location loc, Statement value) {
|
||||
public TypeofNode(Location loc, Node value) {
|
||||
super(loc);
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public static ParseRes<TypeofStatement> parse(Source src, int i) {
|
||||
public static ParseRes<TypeofNode> parse(Source src, int i) {
|
||||
var n = Parsing.skipEmpty(src, i);
|
||||
var loc = src.loc(i + n);
|
||||
|
||||
@ -46,6 +46,6 @@ public class TypeofStatement extends Statement {
|
||||
if (!valRes.isSuccess()) return valRes.chainError(src.loc(i + n), "Expected a value after 'typeof' keyword.");
|
||||
n += valRes.n;
|
||||
|
||||
return ParseRes.res(new TypeofStatement(loc, valRes.result), n);
|
||||
return ParseRes.res(new TypeofNode(loc, valRes.result), n);
|
||||
}
|
||||
}
|
@ -4,12 +4,12 @@ import me.topchetoeu.jscript.common.Instruction;
|
||||
import me.topchetoeu.jscript.common.Operation;
|
||||
import me.topchetoeu.jscript.common.parsing.Location;
|
||||
import me.topchetoeu.jscript.compilation.CompileResult;
|
||||
import me.topchetoeu.jscript.compilation.Statement;
|
||||
import me.topchetoeu.jscript.compilation.values.FunctionStatement;
|
||||
import me.topchetoeu.jscript.compilation.Node;
|
||||
import me.topchetoeu.jscript.compilation.values.FunctionNode;
|
||||
|
||||
public class VariableAssignStatement extends Statement {
|
||||
public class VariableAssignNode extends Node {
|
||||
public final String name;
|
||||
public final Statement value;
|
||||
public final Node value;
|
||||
public final Operation operation;
|
||||
|
||||
@Override public boolean pure() { return false; }
|
||||
@ -19,17 +19,17 @@ public class VariableAssignStatement extends Statement {
|
||||
var i = target.scope.getKey(name);
|
||||
if (operation != null) {
|
||||
target.add(Instruction.loadVar(i));
|
||||
FunctionStatement.compileWithName(value, target, true, name);
|
||||
FunctionNode.compileWithName(value, target, true, name);
|
||||
target.add(Instruction.operation(operation));
|
||||
target.add(Instruction.storeVar(i, pollute));
|
||||
}
|
||||
else {
|
||||
FunctionStatement.compileWithName(value, target, true, name);
|
||||
FunctionNode.compileWithName(value, target, true, name);
|
||||
target.add(Instruction.storeVar(i, pollute));
|
||||
}
|
||||
}
|
||||
|
||||
public VariableAssignStatement(Location loc, String name, Statement val, Operation operation) {
|
||||
public VariableAssignNode(Location loc, String name, Node val, Operation operation) {
|
||||
super(loc);
|
||||
this.name = name;
|
||||
this.value = val;
|
@ -3,9 +3,9 @@ package me.topchetoeu.jscript.compilation.values.operations;
|
||||
import me.topchetoeu.jscript.common.Instruction;
|
||||
import me.topchetoeu.jscript.common.parsing.Location;
|
||||
import me.topchetoeu.jscript.compilation.CompileResult;
|
||||
import me.topchetoeu.jscript.compilation.Statement;
|
||||
import me.topchetoeu.jscript.compilation.Node;
|
||||
|
||||
public class VariableIndexStatement extends Statement {
|
||||
public class VariableIndexNode extends Node {
|
||||
public final int index;
|
||||
|
||||
@Override public boolean pure() { return true; }
|
||||
@ -15,7 +15,7 @@ public class VariableIndexStatement extends Statement {
|
||||
if (pollute) target.add(Instruction.loadVar(index));
|
||||
}
|
||||
|
||||
public VariableIndexStatement(Location loc, int i) {
|
||||
public VariableIndexNode(Location loc, int i) {
|
||||
super(loc);
|
||||
this.index = i;
|
||||
}
|
Loading…
Reference in New Issue
Block a user