Compare commits
5 Commits
0.9.11-bet
...
0.9.14-bet
| Author | SHA1 | Date | |
|---|---|---|---|
|
510422cab7
|
|||
|
79e1d1cfaf
|
|||
|
e0f3274a95
|
|||
| ef5d29105f | |||
|
d8ea6557df
|
2
.github/workflows/tagged-release.yml
vendored
2
.github/workflows/tagged-release.yml
vendored
@@ -3,7 +3,7 @@ name: "tagged-release"
|
|||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
tags:
|
tags:
|
||||||
- "v*"
|
- "*"
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
tagged-release:
|
tagged-release:
|
||||||
|
|||||||
@@ -23,7 +23,3 @@ engine.run(true);
|
|||||||
// Get our result
|
// Get our result
|
||||||
System.out.println(awaitable.await());
|
System.out.println(awaitable.await());
|
||||||
```
|
```
|
||||||
|
|
||||||
## NOTE:
|
|
||||||
|
|
||||||
To setup the typescript bundle in your sources, run `node build.js init-ts`. This will download the latest version of typescript, minify it, and add it to your src folder. If you are going to work with the `node build.js debug|release` command, this is not a necessary step.
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
project_group = me.topchetoeu
|
project_group = me.topchetoeu
|
||||||
project_name = jscript
|
project_name = jscript
|
||||||
project_version = 0.9.11-beta
|
project_version = 0.9.12-beta
|
||||||
main_class = me.topchetoeu.jscript.utils.JScriptRepl
|
main_class = me.topchetoeu.jscript.utils.JScriptRepl
|
||||||
|
|||||||
@@ -0,0 +1,73 @@
|
|||||||
|
package me.topchetoeu.jscript.compilation.control;
|
||||||
|
|
||||||
|
import me.topchetoeu.jscript.common.Instruction;
|
||||||
|
import me.topchetoeu.jscript.common.Location;
|
||||||
|
import me.topchetoeu.jscript.common.Instruction.BreakpointType;
|
||||||
|
import me.topchetoeu.jscript.compilation.CompileResult;
|
||||||
|
import me.topchetoeu.jscript.compilation.Statement;
|
||||||
|
|
||||||
|
public class ForOfStatement extends Statement {
|
||||||
|
public final String varName;
|
||||||
|
public final boolean isDeclaration;
|
||||||
|
public final Statement iterable, body;
|
||||||
|
public final String label;
|
||||||
|
public final Location varLocation;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void declare(CompileResult target) {
|
||||||
|
body.declare(target);
|
||||||
|
if (isDeclaration) target.scope.define(varName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void compile(CompileResult target, boolean pollute) {
|
||||||
|
var key = target.scope.getKey(varName);
|
||||||
|
|
||||||
|
if (key instanceof String) target.add(Instruction.makeVar((String)key));
|
||||||
|
|
||||||
|
iterable.compile(target, true, BreakpointType.STEP_OVER);
|
||||||
|
target.add(Instruction.dup());
|
||||||
|
target.add(Instruction.loadVar("Symbol"));
|
||||||
|
target.add(Instruction.pushValue("iterator"));
|
||||||
|
target.add(Instruction.loadMember()).setLocation(iterable.loc());
|
||||||
|
target.add(Instruction.loadMember()).setLocation(iterable.loc());
|
||||||
|
target.add(Instruction.call(0)).setLocation(iterable.loc());
|
||||||
|
|
||||||
|
int start = target.size();
|
||||||
|
target.add(Instruction.dup());
|
||||||
|
target.add(Instruction.dup());
|
||||||
|
target.add(Instruction.pushValue("next"));
|
||||||
|
target.add(Instruction.loadMember()).setLocation(iterable.loc());
|
||||||
|
target.add(Instruction.call(0)).setLocation(iterable.loc());
|
||||||
|
target.add(Instruction.dup());
|
||||||
|
target.add(Instruction.pushValue("done"));
|
||||||
|
target.add(Instruction.loadMember()).setLocation(iterable.loc());
|
||||||
|
int mid = target.temp();
|
||||||
|
|
||||||
|
target.add(Instruction.pushValue("value"));
|
||||||
|
target.add(Instruction.loadMember()).setLocation(varLocation);
|
||||||
|
target.add(Instruction.storeVar(key)).setLocationAndDebug(iterable.loc(), BreakpointType.STEP_OVER);
|
||||||
|
|
||||||
|
body.compile(target, false, BreakpointType.STEP_OVER);
|
||||||
|
|
||||||
|
int end = target.size();
|
||||||
|
|
||||||
|
WhileStatement.replaceBreaks(target, label, mid + 1, end, start, end + 1);
|
||||||
|
|
||||||
|
target.add(Instruction.jmp(start - end));
|
||||||
|
target.add(Instruction.discard());
|
||||||
|
target.add(Instruction.discard());
|
||||||
|
target.set(mid, Instruction.jmpIf(end - mid + 1));
|
||||||
|
if (pollute) target.add(Instruction.pushUndefined());
|
||||||
|
}
|
||||||
|
|
||||||
|
public ForOfStatement(Location loc, Location varLocation, String label, boolean isDecl, String varName, Statement object, Statement body) {
|
||||||
|
super(loc);
|
||||||
|
this.varLocation = varLocation;
|
||||||
|
this.label = label;
|
||||||
|
this.isDeclaration = isDecl;
|
||||||
|
this.varName = varName;
|
||||||
|
this.iterable = object;
|
||||||
|
this.body = body;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1777,6 +1777,46 @@ public class Parsing {
|
|||||||
|
|
||||||
return ParseRes.res(new ForInStatement(loc, nameLoc, labelRes.result, isDecl, nameRes.result, varVal, objRes.result, bodyRes.result), n);
|
return ParseRes.res(new ForInStatement(loc, nameLoc, labelRes.result, isDecl, nameRes.result, varVal, objRes.result, bodyRes.result), n);
|
||||||
}
|
}
|
||||||
|
public static ParseRes<ForOfStatement> parseForOf(Filename filename, List<Token> tokens, int i) {
|
||||||
|
var loc = getLoc(filename, tokens, i);
|
||||||
|
int n = 0;
|
||||||
|
|
||||||
|
var labelRes = parseLabel(tokens, i + n);
|
||||||
|
var isDecl = false;
|
||||||
|
n += labelRes.n;
|
||||||
|
|
||||||
|
if (!isIdentifier(tokens, i + n++, "for")) return ParseRes.failed();
|
||||||
|
if (!isOperator(tokens, i + n++, Operator.PAREN_OPEN)) return ParseRes.error(loc, "Expected a open paren after 'for'.");
|
||||||
|
|
||||||
|
if (isIdentifier(tokens, i + n, "var")) {
|
||||||
|
isDecl = true;
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
|
||||||
|
var nameRes = parseIdentifier(tokens, i + n);
|
||||||
|
if (!nameRes.isSuccess()) return ParseRes.error(loc, "Expected a variable name for 'for' loop.");
|
||||||
|
var nameLoc = getLoc(filename, tokens, i + n);
|
||||||
|
n += nameRes.n;
|
||||||
|
|
||||||
|
if (!isIdentifier(tokens, i + n++, "of")) {
|
||||||
|
if (nameRes.result.equals("const")) return ParseRes.error(loc, "'const' declarations are not supported.");
|
||||||
|
else if (nameRes.result.equals("let")) return ParseRes.error(loc, "'let' declarations are not supported.");
|
||||||
|
else return ParseRes.error(loc, "Expected 'of' keyword after variable declaration.");
|
||||||
|
}
|
||||||
|
|
||||||
|
var objRes = parseValue(filename, tokens, i + n, 0);
|
||||||
|
if (!objRes.isSuccess()) return ParseRes.error(loc, "Expected a value.", objRes);
|
||||||
|
n += objRes.n;
|
||||||
|
|
||||||
|
if (!isOperator(tokens, i + n++, Operator.PAREN_CLOSE)) return ParseRes.error(loc, "Expected a closing paren after for.");
|
||||||
|
|
||||||
|
|
||||||
|
var bodyRes = parseStatement(filename, tokens, i + n);
|
||||||
|
if (!bodyRes.isSuccess()) return ParseRes.error(loc, "Expected a for body.", bodyRes);
|
||||||
|
n += bodyRes.n;
|
||||||
|
|
||||||
|
return ParseRes.res(new ForOfStatement(loc, nameLoc, labelRes.result, isDecl, nameRes.result, objRes.result, bodyRes.result), n);
|
||||||
|
}
|
||||||
public static ParseRes<TryStatement> parseCatch(Filename filename, List<Token> tokens, int i) {
|
public static ParseRes<TryStatement> parseCatch(Filename filename, List<Token> tokens, int i) {
|
||||||
var loc = getLoc(filename, tokens, i);
|
var loc = getLoc(filename, tokens, i);
|
||||||
int n = 0;
|
int n = 0;
|
||||||
@@ -1833,6 +1873,7 @@ public class Parsing {
|
|||||||
parseSwitch(filename, tokens, i),
|
parseSwitch(filename, tokens, i),
|
||||||
parseFor(filename, tokens, i),
|
parseFor(filename, tokens, i),
|
||||||
parseForIn(filename, tokens, i),
|
parseForIn(filename, tokens, i),
|
||||||
|
parseForOf(filename, tokens, i),
|
||||||
parseDoWhile(filename, tokens, i),
|
parseDoWhile(filename, tokens, i),
|
||||||
parseCatch(filename, tokens, i),
|
parseCatch(filename, tokens, i),
|
||||||
parseCompound(filename, tokens, i),
|
parseCompound(filename, tokens, i),
|
||||||
|
|||||||
@@ -195,7 +195,24 @@ public class NativeWrapperProvider implements WrapperProvider {
|
|||||||
if (props.contains(key) || nonProps.contains(key)) repeat = true;
|
if (props.contains(key) || nonProps.contains(key)) repeat = true;
|
||||||
else {
|
else {
|
||||||
try {
|
try {
|
||||||
obj.defineProperty(null, key, Values.normalize(new Context(env), field.get(null)), true, true, false);
|
if (Modifier.isStatic(field.getModifiers())) {
|
||||||
|
obj.defineProperty(null, key, Values.normalize(new Context(env), field.get(null)), true, true, false);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
obj.defineProperty(
|
||||||
|
null, key,
|
||||||
|
new NativeFunction("get " + key, args -> {
|
||||||
|
try { return field.get(args.self(clazz)); }
|
||||||
|
catch (IllegalAccessException e) { e.printStackTrace(); return null; }
|
||||||
|
}),
|
||||||
|
Modifier.isFinal(field.getModifiers()) ? null : new NativeFunction("get " + key, args -> {
|
||||||
|
try { field.set(args.self(clazz), args.convert(0, field.getType())); }
|
||||||
|
catch (IllegalAccessException e) { e.printStackTrace(); }
|
||||||
|
return null;
|
||||||
|
}),
|
||||||
|
true, false
|
||||||
|
);
|
||||||
|
}
|
||||||
nonProps.add(key);
|
nonProps.add(key);
|
||||||
}
|
}
|
||||||
catch (IllegalArgumentException | IllegalAccessException e) { }
|
catch (IllegalArgumentException | IllegalAccessException e) { }
|
||||||
|
|||||||
Reference in New Issue
Block a user