mlogjs 0.4.1 → 0.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Scope.d.ts +1 -0
- package/dist/bin.cjs.map +1 -0
- package/dist/handlers/Statements.d.ts +1 -0
- package/dist/index.cjs +152 -48
- package/dist/index.cjs.map +1 -0
- package/dist/index.mjs +152 -48
- package/dist/index.mjs.map +1 -0
- package/dist/instructions/SetInstruction.d.ts +2 -0
- package/dist/macros/Function.d.ts +2 -2
- package/dist/macros/Math.d.ts +2 -1
- package/dist/operators.d.ts +4 -4
- package/dist/types.d.ts +3 -0
- package/dist/values/BaseValue.d.ts +1 -0
- package/lib/commands.d.ts +300 -30
- package/lib/eslib/lib.es5.d.ts +23 -0
- package/lib/globals.d.ts +2 -3
- package/lib/helpers.d.ts +2 -1
- package/lib/kinds.d.ts +5 -2
- package/lib/traits.d.ts +10 -6
- package/package.json +1 -6
package/dist/Scope.d.ts
CHANGED
|
@@ -11,6 +11,7 @@ export declare class Scope implements IScope {
|
|
|
11
11
|
break: AddressResolver;
|
|
12
12
|
continue: AddressResolver;
|
|
13
13
|
function: IFunctionValue;
|
|
14
|
+
label?: string;
|
|
14
15
|
constructor(values: Record<string, IValueOwner | null>, parent?: IScope | null, stacked?: boolean, ntemp?: number, name?: string, inst?: IInstruction[]);
|
|
15
16
|
copy(): IScope;
|
|
16
17
|
createScope(): IScope;
|
package/dist/bin.cjs.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bin.cjs","sources":["../src/bin.ts"],"sourcesContent":[null],"names":["yargs","hideBin","path","existsSync","Compiler","readFileSync","chalk","resolve","highlight","writeFileSync","parse","join"],"mappings":";;;;;;;;;;;;;;;;AAQAA,yBAAK,CAACC,eAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;AACzB,KAAA,OAAO,CACN,iBAAiB,EACjB,uCAAuC,EACvC,KAAK,IAAG;AACN,IAAA,OAAO,KAAK;SACT,UAAU,CAAC,MAAM,EAAE;AAClB,QAAA,QAAQ,EAAE,6BAA6B;AACvC,QAAA,IAAI,EAAE,QAAQ;KACf,CAAC;SACD,UAAU,CAAC,KAAK,EAAE;AACjB,QAAA,QAAQ,EAAE,yBAAyB;AACnC,QAAA,IAAI,EAAE,QAAQ;KACf,CAAC;SACD,MAAM,CAAC,eAAe,EAAE;AACvB,QAAA,IAAI,EAAE,SAAS;AACf,QAAA,OAAO,EAAE,KAAK;AACd,QAAA,QAAQ,EACN,4EAA4E;AAC/E,KAAA,CAAC,CAAC;AACP,CAAC,EACD,IAAI,IAAG;AACL,IAAA,MAAMC,MAAI,GAAG,IAAI,CAAC,IAAI,CAAC;AACvB,IAAA,IAAI,CAACA,MAAI;AAAE,QAAA,OAAO,OAAO,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAC;AAChE,IAAA,IAAI,CAACC,aAAU,CAACD,MAAI,CAAC;QACnB,OAAO,OAAO,CAAC,GAAG,CAAC,WAAWA,MAAI,CAAA,eAAA,CAAiB,CAAC,CAAC;IACvD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,cAAc,CAACA,MAAI,CAAC,CAAC;IAC7C,IAAIA,MAAI,IAAI,GAAG;AACb,QAAA,OAAO,OAAO,CAAC,GAAG,CAAC,mDAAmD,CAAC,CAAC;AAC1E,IAAA,MAAM,QAAQ,GAAG,IAAIE,kBAAQ,CAAC;AAC5B,QAAA,YAAY,EAAE,IAAI,CAAC,eAAe,CAAC;AACpC,KAAA,CAAC,CAAC;IACH,MAAM,IAAI,GAAGC,eAAY,CAACH,MAAI,EAAE,MAAM,CAAC,CAAC;AACxC,IAAA,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,GAAG,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;AAC/C,IAAA,IAAI,KAAK,EAAE;AACT,QAAA,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE;YACd,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,CAAC;YAClC,OAAO;AACR,SAAA;QACD,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,KAAK,CAAC,GAAG,CAAC;QAEjC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;AAC/B,QAAA,OAAO,CAAC,GAAG,CACTI,yBAAK,CAAC,UAAU,CAAC,CAACC,YAAO,CAACL,MAAI,CAAC,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CACtE,CAAC;AACF,QAAA,KACE,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC,CAAC,EACnC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,EACxC,CAAC,EAAE,EACH;AACA,YAAA,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAChB,YAAA,IAAI,CAAC,KAAK,KAAK,CAAC,IAAI;gBAAE,SAAS;AAC/B,YAAA,MAAM,IAAI,GAAGI,yBAAK,CAAC,IAAI,CAAC,CAAG,EAAA,CAAC,CAAK,GAAA,CAAA,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;AACpD,YAAA,OAAO,CAAC,GAAG,CAAC,IAAI,GAAGE,sBAAS,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;YAC5D,OAAO,CAAC,GAAG,CACTF,yBAAK,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,GAAG,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,CAC/D,CAAC;AACH,SAAA;QAED,OAAO;AACR,KAAA;AACD,IAAAG,gBAAa,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IAC3B,OAAO,CAAC,GAAG,CACT,CAAA,kBAAA,EAAqBP,MAAI,CAA8B,2BAAA,EAAA,GAAG,CAAG,CAAA,CAAA,CAC9D,CAAC;AACJ,CAAC,CACF;AACA,KAAA,IAAI,EAAE;KACN,UAAU,CAAC,QAAQ,CAAC;AACpB,KAAA,aAAa,EAAE;AACf,KAAA,KAAK,EAAE,CAAC;AAEX,SAAS,cAAc,CAACA,MAAY,EAAA;AAClC,IAAA,MAAM,MAAM,GAAGQ,UAAK,CAACR,MAAI,CAAC,CAAC;AAC3B,IAAA,OAAOS,SAAI,CAAC,MAAM,CAAC,GAAG,EAAE,CAAG,EAAA,MAAM,CAAC,IAAI,CAAO,KAAA,CAAA,CAAC,CAAC;AACjD;;"}
|
|
@@ -3,3 +3,4 @@ export declare const ExpressionStatement: THandler<IValue | null>;
|
|
|
3
3
|
export declare const BreakStatement: THandler<null>;
|
|
4
4
|
export declare const ContinueStatement: THandler<null>;
|
|
5
5
|
export declare const ReturnStatement: THandler<IValue | null>;
|
|
6
|
+
export declare const LabeledStatement: THandler<null>;
|
package/dist/index.cjs
CHANGED
|
@@ -138,7 +138,7 @@ const arithmeticAssignmentOperators = [
|
|
|
138
138
|
"-=",
|
|
139
139
|
"/=",
|
|
140
140
|
];
|
|
141
|
-
const logicalAssignmentOperators = ["&&=", "||="];
|
|
141
|
+
const logicalAssignmentOperators = ["&&=", "||=", "??="];
|
|
142
142
|
const bitwiseAssignmentOperators = [
|
|
143
143
|
"<<=",
|
|
144
144
|
">>=",
|
|
@@ -231,8 +231,22 @@ class SetInstruction extends InstructionBase {
|
|
|
231
231
|
constructor(store, value) {
|
|
232
232
|
super("set", store, value);
|
|
233
233
|
}
|
|
234
|
+
get store() {
|
|
235
|
+
return this.args[1];
|
|
236
|
+
}
|
|
237
|
+
get value() {
|
|
238
|
+
return this.args[2];
|
|
239
|
+
}
|
|
234
240
|
get hidden() {
|
|
235
|
-
|
|
241
|
+
const { store, value } = this;
|
|
242
|
+
return (this._hidden ||
|
|
243
|
+
// assignment to discarded value
|
|
244
|
+
!store.owner ||
|
|
245
|
+
// self assignment of a store
|
|
246
|
+
(!!store.owner &&
|
|
247
|
+
store instanceof StoreValue &&
|
|
248
|
+
value instanceof StoreValue &&
|
|
249
|
+
store.owner === value.owner));
|
|
236
250
|
}
|
|
237
251
|
}
|
|
238
252
|
|
|
@@ -341,6 +355,34 @@ class BaseValue extends VoidValue {
|
|
|
341
355
|
const temp = new StoreValue(scope);
|
|
342
356
|
return [temp, [...inst, new OperationInstruction("not", temp, that, null)]];
|
|
343
357
|
}
|
|
358
|
+
// requires special handling
|
|
359
|
+
// the handler should give an object value to allow the lazy evaluation
|
|
360
|
+
"??"(scope, other) {
|
|
361
|
+
const [left, leftInst] = this.eval(scope);
|
|
362
|
+
const nullLiteral = new LiteralValue(null);
|
|
363
|
+
const endAdress = new LiteralValue(null);
|
|
364
|
+
const [nullTest] = left["=="](scope, nullLiteral);
|
|
365
|
+
if (nullTest instanceof LiteralValue) {
|
|
366
|
+
if (nullTest.data)
|
|
367
|
+
return other.eval(scope);
|
|
368
|
+
else
|
|
369
|
+
return [left, leftInst];
|
|
370
|
+
}
|
|
371
|
+
const [right, rightInst] = other.eval(scope);
|
|
372
|
+
const result = new StoreValue(scope);
|
|
373
|
+
result.ensureOwned();
|
|
374
|
+
return [
|
|
375
|
+
result,
|
|
376
|
+
[
|
|
377
|
+
...leftInst,
|
|
378
|
+
...result["="](scope, left)[1],
|
|
379
|
+
new JumpInstruction(endAdress, EJumpKind.NotEqual, result, nullLiteral),
|
|
380
|
+
...rightInst,
|
|
381
|
+
...result["="](scope, right)[1],
|
|
382
|
+
new AddressResolver(endAdress),
|
|
383
|
+
],
|
|
384
|
+
];
|
|
385
|
+
}
|
|
344
386
|
}
|
|
345
387
|
const operatorMap$1 = {
|
|
346
388
|
"==": "equal",
|
|
@@ -397,6 +439,7 @@ const assignmentToBinary = {
|
|
|
397
439
|
"<<=": "<<",
|
|
398
440
|
"&&=": "&&",
|
|
399
441
|
"||=": "||",
|
|
442
|
+
"??=": "??",
|
|
400
443
|
};
|
|
401
444
|
for (const op in assignmentToBinary) {
|
|
402
445
|
BaseValue.prototype[op] = function (scope, value) {
|
|
@@ -1002,35 +1045,26 @@ const BinaryExpression = LRExpression;
|
|
|
1002
1045
|
const LogicalExpression = (c, scope, node) => {
|
|
1003
1046
|
if (node.operator !== "??")
|
|
1004
1047
|
return LRExpression(c, scope, node);
|
|
1005
|
-
const
|
|
1006
|
-
|
|
1048
|
+
const other = lazyValue({
|
|
1049
|
+
eval: scope => c.handleEval(scope, node.right),
|
|
1050
|
+
consume: scope => c.handleConsume(scope, node.right),
|
|
1051
|
+
});
|
|
1007
1052
|
const [left, leftInst] = c.handleEval(scope, node.left);
|
|
1008
|
-
const [
|
|
1009
|
-
|
|
1010
|
-
if (nullTest.data)
|
|
1011
|
-
return c.handleEval(scope, node.right);
|
|
1012
|
-
else
|
|
1013
|
-
return [left, leftInst];
|
|
1014
|
-
}
|
|
1015
|
-
const [right, rightInst] = c.handleEval(scope, node.right);
|
|
1016
|
-
const result = new StoreValue(scope);
|
|
1017
|
-
result.ensureOwned();
|
|
1018
|
-
return [
|
|
1019
|
-
result,
|
|
1020
|
-
[
|
|
1021
|
-
...leftInst,
|
|
1022
|
-
...result["="](scope, left)[1],
|
|
1023
|
-
new JumpInstruction(endAdress, EJumpKind.NotEqual, result, nullLiteral),
|
|
1024
|
-
...rightInst,
|
|
1025
|
-
...result["="](scope, right)[1],
|
|
1026
|
-
new AddressResolver(endAdress),
|
|
1027
|
-
],
|
|
1028
|
-
];
|
|
1053
|
+
const [result, resultInst] = left["??"](scope, other);
|
|
1054
|
+
return [result, [...leftInst, ...resultInst]];
|
|
1029
1055
|
};
|
|
1030
1056
|
const AssignmentExpression = (c, scope, node) => {
|
|
1031
1057
|
const [left, leftInst] = c.handle(scope, node.left);
|
|
1032
1058
|
// doesn't need to consume because the operators already do that
|
|
1033
|
-
const [right, rightInst] =
|
|
1059
|
+
const [right, rightInst] = node.operator !== "??="
|
|
1060
|
+
? c.handleEval(scope, node.right)
|
|
1061
|
+
: [
|
|
1062
|
+
lazyValue({
|
|
1063
|
+
eval: scope => c.handleEval(scope, node.right),
|
|
1064
|
+
consume: scope => c.handleConsume(scope, node.right),
|
|
1065
|
+
}),
|
|
1066
|
+
[],
|
|
1067
|
+
];
|
|
1034
1068
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
1035
1069
|
const [op, opInst] = left[node.operator](scope, right);
|
|
1036
1070
|
return [op, [...leftInst, ...rightInst, ...opInst]];
|
|
@@ -1078,7 +1112,13 @@ const ConditionalExpression = (c, scope, node) => {
|
|
|
1078
1112
|
new AddressResolver(endExpressionAdress),
|
|
1079
1113
|
],
|
|
1080
1114
|
];
|
|
1081
|
-
};
|
|
1115
|
+
};
|
|
1116
|
+
function lazyValue(options) {
|
|
1117
|
+
const value = new VoidValue();
|
|
1118
|
+
value.eval = options.eval;
|
|
1119
|
+
value.consume = options.consume;
|
|
1120
|
+
return value;
|
|
1121
|
+
}
|
|
1082
1122
|
|
|
1083
1123
|
const Identifier = (c, scope, node) => {
|
|
1084
1124
|
return [scope.get(node.name), []];
|
|
@@ -1087,14 +1127,18 @@ const Identifier = (c, scope, node) => {
|
|
|
1087
1127
|
const ExpressionStatement = (c, scope, node) => {
|
|
1088
1128
|
return c.handle(scope, node.expression);
|
|
1089
1129
|
};
|
|
1090
|
-
const BreakStatement = (_, scope) => {
|
|
1130
|
+
const BreakStatement = (_, scope, node) => {
|
|
1131
|
+
const label = node.label?.name;
|
|
1132
|
+
const target = label ? findScopeLabel(scope, label) : scope;
|
|
1091
1133
|
const addr = new LiteralValue(null);
|
|
1092
|
-
|
|
1134
|
+
target.break.bind(addr);
|
|
1093
1135
|
return [null, [new BreakInstruction(addr)]];
|
|
1094
1136
|
};
|
|
1095
|
-
const ContinueStatement = (_, scope) => {
|
|
1137
|
+
const ContinueStatement = (_, scope, node) => {
|
|
1096
1138
|
const addr = new LiteralValue(null);
|
|
1097
|
-
|
|
1139
|
+
const label = node.label?.name;
|
|
1140
|
+
const target = label ? findScopeLabel(scope, label) : scope;
|
|
1141
|
+
target.continue.bind(addr);
|
|
1098
1142
|
return [null, [new ContinueInstruction(addr)]];
|
|
1099
1143
|
};
|
|
1100
1144
|
const ReturnStatement = (c, scope, node) => {
|
|
@@ -1103,7 +1147,24 @@ const ReturnStatement = (c, scope, node) => {
|
|
|
1103
1147
|
: [null, []];
|
|
1104
1148
|
const [ret, retInst] = scope.function.return(scope, arg);
|
|
1105
1149
|
return [ret, [...argInst, ...retInst]];
|
|
1106
|
-
};
|
|
1150
|
+
};
|
|
1151
|
+
const LabeledStatement = (c, scope, node) => {
|
|
1152
|
+
const inner = scope.createScope();
|
|
1153
|
+
inner.label = node.label.name;
|
|
1154
|
+
const end = new LiteralValue(null);
|
|
1155
|
+
const endAdress = new AddressResolver(end).bindBreak(inner);
|
|
1156
|
+
const [, bodyInst] = c.handle(inner, node.body);
|
|
1157
|
+
return [null, [...bodyInst, endAdress]];
|
|
1158
|
+
};
|
|
1159
|
+
function findScopeLabel(scope, label) {
|
|
1160
|
+
let current = scope;
|
|
1161
|
+
while (current !== null) {
|
|
1162
|
+
if (current.label === label)
|
|
1163
|
+
return current;
|
|
1164
|
+
current = current.parent;
|
|
1165
|
+
}
|
|
1166
|
+
throw new CompilerError(`Could not find label "${label}"`);
|
|
1167
|
+
}
|
|
1107
1168
|
|
|
1108
1169
|
const IfStatement = (c, scope, node) => {
|
|
1109
1170
|
const inst = [];
|
|
@@ -1188,25 +1249,33 @@ const SwitchStatement = (c, scope, node) => {
|
|
|
1188
1249
|
const WhileStatement = (c, scope, node) => {
|
|
1189
1250
|
const lines = [];
|
|
1190
1251
|
const [test, testLines] = c.handleConsume(scope, node.test);
|
|
1252
|
+
const childScope = scope.createScope();
|
|
1191
1253
|
const startLoopAddr = new LiteralValue(null);
|
|
1192
1254
|
const endLoopAddr = new LiteralValue(null);
|
|
1193
|
-
const startLoopLine = new AddressResolver(startLoopAddr).bindContinue(
|
|
1194
|
-
const endLoopLine = new AddressResolver(endLoopAddr).bindBreak(
|
|
1255
|
+
const startLoopLine = new AddressResolver(startLoopAddr).bindContinue(childScope);
|
|
1256
|
+
const endLoopLine = new AddressResolver(endLoopAddr).bindBreak(childScope);
|
|
1257
|
+
if (scope.label) {
|
|
1258
|
+
startLoopLine.bindContinue(scope);
|
|
1259
|
+
}
|
|
1195
1260
|
if (test instanceof LiteralValue) {
|
|
1196
1261
|
if (test.data) {
|
|
1197
|
-
lines.push(startLoopLine, ...c.handle(
|
|
1262
|
+
lines.push(startLoopLine, ...c.handle(childScope, node.body)[1], new JumpInstruction(startLoopAddr, EJumpKind.Always), endLoopLine);
|
|
1198
1263
|
}
|
|
1199
1264
|
return [null, lines];
|
|
1200
1265
|
}
|
|
1201
|
-
lines.push(startLoopLine, ...testLines, new JumpInstruction(endLoopAddr, EJumpKind.Equal, test, new LiteralValue(0)), ...withAlwaysRuns(c.handle(
|
|
1266
|
+
lines.push(startLoopLine, ...testLines, new JumpInstruction(endLoopAddr, EJumpKind.Equal, test, new LiteralValue(0)), ...withAlwaysRuns(c.handle(childScope, node.body), false)[1], new JumpInstruction(startLoopAddr, EJumpKind.Always), endLoopLine);
|
|
1202
1267
|
return [null, lines];
|
|
1203
1268
|
};
|
|
1204
1269
|
const DoWhileStatement = (c, scope, node) => {
|
|
1205
1270
|
const lines = [];
|
|
1206
1271
|
const [test, testLines] = c.handleConsume(scope, node.test);
|
|
1272
|
+
const childScope = scope.createScope();
|
|
1207
1273
|
const startLoopAddr = new LiteralValue(null);
|
|
1208
|
-
const startLoopLine = new AddressResolver(startLoopAddr).bindContinue(
|
|
1209
|
-
|
|
1274
|
+
const startLoopLine = new AddressResolver(startLoopAddr).bindContinue(childScope);
|
|
1275
|
+
if (scope.label) {
|
|
1276
|
+
startLoopLine.bindContinue(scope);
|
|
1277
|
+
}
|
|
1278
|
+
const [, bodyLines] = c.handle(childScope, node.body);
|
|
1210
1279
|
if (test instanceof LiteralValue) {
|
|
1211
1280
|
if (!test.data)
|
|
1212
1281
|
return [null, [...lines, ...bodyLines]];
|
|
@@ -1224,8 +1293,8 @@ const DoWhileStatement = (c, scope, node) => {
|
|
|
1224
1293
|
return [null, lines];
|
|
1225
1294
|
};
|
|
1226
1295
|
|
|
1227
|
-
const ForStatement = (c,
|
|
1228
|
-
scope =
|
|
1296
|
+
const ForStatement = (c, parentScope, node) => {
|
|
1297
|
+
const scope = parentScope.createScope();
|
|
1229
1298
|
const initInst = node.init ? c.handle(scope, node.init)[1] : [];
|
|
1230
1299
|
const [test, testLines] = node.test
|
|
1231
1300
|
? c.handleConsume(scope, node.test)
|
|
@@ -1235,6 +1304,9 @@ const ForStatement = (c, scope, node) => {
|
|
|
1235
1304
|
const endLoopAddr = new LiteralValue(null);
|
|
1236
1305
|
const startLoopLine = new AddressResolver(startLoopAddr).bindContinue(scope);
|
|
1237
1306
|
const endLoopLine = new AddressResolver(endLoopAddr).bindBreak(scope);
|
|
1307
|
+
if (parentScope.label) {
|
|
1308
|
+
startLoopLine.bindContinue(parentScope);
|
|
1309
|
+
}
|
|
1238
1310
|
return [
|
|
1239
1311
|
null,
|
|
1240
1312
|
[
|
|
@@ -1657,6 +1729,7 @@ var handlers = /*#__PURE__*/Object.freeze({
|
|
|
1657
1729
|
BreakStatement: BreakStatement,
|
|
1658
1730
|
ContinueStatement: ContinueStatement,
|
|
1659
1731
|
ReturnStatement: ReturnStatement,
|
|
1732
|
+
LabeledStatement: LabeledStatement,
|
|
1660
1733
|
IfStatement: IfStatement,
|
|
1661
1734
|
SwitchStatement: SwitchStatement,
|
|
1662
1735
|
WhileStatement: WhileStatement,
|
|
@@ -1689,7 +1762,7 @@ class MacroFunction extends VoidValue {
|
|
|
1689
1762
|
constructor(fn) {
|
|
1690
1763
|
super();
|
|
1691
1764
|
this.macro = true;
|
|
1692
|
-
this.
|
|
1765
|
+
this.mutability = EMutability.constant;
|
|
1693
1766
|
this.fn = fn;
|
|
1694
1767
|
}
|
|
1695
1768
|
call(scope, args) {
|
|
@@ -1724,8 +1797,23 @@ const mathOperations = {
|
|
|
1724
1797
|
sqrt: a => Math.sqrt(a),
|
|
1725
1798
|
rand: null,
|
|
1726
1799
|
};
|
|
1727
|
-
function
|
|
1728
|
-
|
|
1800
|
+
function mathConstant(scope, name) {
|
|
1801
|
+
return new ValueOwner({
|
|
1802
|
+
scope,
|
|
1803
|
+
constant: true,
|
|
1804
|
+
name,
|
|
1805
|
+
value: assign(new StoreValue(scope), {
|
|
1806
|
+
mutability: EMutability.constant,
|
|
1807
|
+
}),
|
|
1808
|
+
}).value;
|
|
1809
|
+
}
|
|
1810
|
+
function createMacroMathOperations(scope) {
|
|
1811
|
+
const macroMathOperations = {
|
|
1812
|
+
PI: mathConstant(scope, "@pi"),
|
|
1813
|
+
E: mathConstant(scope, "@e"),
|
|
1814
|
+
degToRad: mathConstant(scope, "@degToRad"),
|
|
1815
|
+
radToDeg: mathConstant(scope, "@radToDeg"),
|
|
1816
|
+
};
|
|
1729
1817
|
for (const key in mathOperations) {
|
|
1730
1818
|
const fn = mathOperations[key];
|
|
1731
1819
|
macroMathOperations[key] = new MacroFunction((scope, a, b) => {
|
|
@@ -1750,8 +1838,8 @@ function createMacroMathOperations() {
|
|
|
1750
1838
|
return macroMathOperations;
|
|
1751
1839
|
}
|
|
1752
1840
|
class MlogMath extends ObjectValue {
|
|
1753
|
-
constructor() {
|
|
1754
|
-
super(createMacroMathOperations());
|
|
1841
|
+
constructor(scope) {
|
|
1842
|
+
super(createMacroMathOperations(scope));
|
|
1755
1843
|
}
|
|
1756
1844
|
}
|
|
1757
1845
|
// op angle result a b
|
|
@@ -2425,6 +2513,7 @@ class SetRule extends ObjectValue {
|
|
|
2425
2513
|
solarMultiplier: { args: ["multiplier"] },
|
|
2426
2514
|
buildSpeed: { args: ["team", "multiplier"] },
|
|
2427
2515
|
unitBuildSpeed: { args: ["team", "multiplier"] },
|
|
2516
|
+
unitCost: { args: ["team", "multiplier"] },
|
|
2428
2517
|
unitDamage: { args: ["team", "multiplier"] },
|
|
2429
2518
|
blockHealth: { args: ["team", "multiplier"] },
|
|
2430
2519
|
blockDamage: { args: ["team", "multiplier"] },
|
|
@@ -2444,6 +2533,7 @@ class SetRule extends ObjectValue {
|
|
|
2444
2533
|
}
|
|
2445
2534
|
case "buildSpeed":
|
|
2446
2535
|
case "unitBuildSpeed":
|
|
2536
|
+
case "unitCost":
|
|
2447
2537
|
case "unitDamage":
|
|
2448
2538
|
case "blockHealth":
|
|
2449
2539
|
case "blockDamage":
|
|
@@ -2451,7 +2541,7 @@ class SetRule extends ObjectValue {
|
|
|
2451
2541
|
case "rtsMinSquad": {
|
|
2452
2542
|
const [team, value] = args;
|
|
2453
2543
|
params[1] = team;
|
|
2454
|
-
params[
|
|
2544
|
+
params[0] = value;
|
|
2455
2545
|
break;
|
|
2456
2546
|
}
|
|
2457
2547
|
default:
|
|
@@ -2812,7 +2902,7 @@ function initScope(scope) {
|
|
|
2812
2902
|
scope.hardSet("getVar", new GetGlobal(EMutability.mutable));
|
|
2813
2903
|
scope.hardSet("concat", new Concat());
|
|
2814
2904
|
scope.hardSet("asm", new Asm());
|
|
2815
|
-
scope.hardSet("Math", new MlogMath());
|
|
2905
|
+
scope.hardSet("Math", new MlogMath(scope));
|
|
2816
2906
|
scope.hardSet("Memory", new MemoryBuilder());
|
|
2817
2907
|
// commands
|
|
2818
2908
|
scope.hardSet("draw", new Draw());
|
|
@@ -2952,7 +3042,7 @@ class Compiler {
|
|
|
2952
3042
|
*/
|
|
2953
3043
|
handleMany(scope, nodes, handler) {
|
|
2954
3044
|
const lines = [];
|
|
2955
|
-
for (const node of nodes) {
|
|
3045
|
+
for (const node of hoistedFunctionNodes(nodes)) {
|
|
2956
3046
|
const [, nodeLines] = this.handle(scope, node, handler && (() => handler(node)));
|
|
2957
3047
|
lines.push(...nodeLines);
|
|
2958
3048
|
}
|
|
@@ -2982,6 +3072,20 @@ function hideRedundantJumps(inst) {
|
|
|
2982
3072
|
current = inst[searchIndex];
|
|
2983
3073
|
}
|
|
2984
3074
|
}
|
|
3075
|
+
}
|
|
3076
|
+
function* hoistedFunctionNodes(nodes) {
|
|
3077
|
+
// sorting is O(n long n) while this is just O(n)
|
|
3078
|
+
// besides, it's better not to modify the node array
|
|
3079
|
+
for (const node of nodes) {
|
|
3080
|
+
if (node.type === "FunctionDeclaration") {
|
|
3081
|
+
yield node;
|
|
3082
|
+
}
|
|
3083
|
+
}
|
|
3084
|
+
for (const node of nodes) {
|
|
3085
|
+
if (node.type !== "FunctionDeclaration") {
|
|
3086
|
+
yield node;
|
|
3087
|
+
}
|
|
3088
|
+
}
|
|
2985
3089
|
}
|
|
2986
3090
|
|
|
2987
3091
|
exports.Compiler = Compiler;
|