Convert code in src/core/function.js
to use "normal" classes
All of this code predates the existence of native JS classes, however we can now clean this up a bit. This patch thus let us remove some variable "shadowing" from the code.
This commit is contained in:
parent
061637d3f4
commit
e69e8622a9
@ -635,26 +635,28 @@ var PostScriptStack = (function PostScriptStackClosure() {
|
|||||||
var MAX_STACK_SIZE = 100;
|
var MAX_STACK_SIZE = 100;
|
||||||
|
|
||||||
// eslint-disable-next-line no-shadow
|
// eslint-disable-next-line no-shadow
|
||||||
function PostScriptStack(initialStack) {
|
class PostScriptStack {
|
||||||
this.stack = !initialStack
|
constructor(initialStack) {
|
||||||
? []
|
this.stack = !initialStack
|
||||||
: Array.prototype.slice.call(initialStack, 0);
|
? []
|
||||||
}
|
: Array.prototype.slice.call(initialStack, 0);
|
||||||
|
}
|
||||||
|
|
||||||
PostScriptStack.prototype = {
|
push(value) {
|
||||||
push: function PostScriptStack_push(value) {
|
|
||||||
if (this.stack.length >= MAX_STACK_SIZE) {
|
if (this.stack.length >= MAX_STACK_SIZE) {
|
||||||
throw new Error("PostScript function stack overflow.");
|
throw new Error("PostScript function stack overflow.");
|
||||||
}
|
}
|
||||||
this.stack.push(value);
|
this.stack.push(value);
|
||||||
},
|
}
|
||||||
pop: function PostScriptStack_pop() {
|
|
||||||
|
pop() {
|
||||||
if (this.stack.length <= 0) {
|
if (this.stack.length <= 0) {
|
||||||
throw new Error("PostScript function stack underflow.");
|
throw new Error("PostScript function stack underflow.");
|
||||||
}
|
}
|
||||||
return this.stack.pop();
|
return this.stack.pop();
|
||||||
},
|
}
|
||||||
copy: function PostScriptStack_copy(n) {
|
|
||||||
|
copy(n) {
|
||||||
if (this.stack.length + n >= MAX_STACK_SIZE) {
|
if (this.stack.length + n >= MAX_STACK_SIZE) {
|
||||||
throw new Error("PostScript function stack overflow.");
|
throw new Error("PostScript function stack overflow.");
|
||||||
}
|
}
|
||||||
@ -662,12 +664,14 @@ var PostScriptStack = (function PostScriptStackClosure() {
|
|||||||
for (var i = stack.length - n, j = n - 1; j >= 0; j--, i++) {
|
for (var i = stack.length - n, j = n - 1; j >= 0; j--, i++) {
|
||||||
stack.push(stack[i]);
|
stack.push(stack[i]);
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
index: function PostScriptStack_index(n) {
|
|
||||||
|
index(n) {
|
||||||
this.push(this.stack[this.stack.length - n - 1]);
|
this.push(this.stack[this.stack.length - n - 1]);
|
||||||
},
|
}
|
||||||
|
|
||||||
// rotate the last n stack elements p times
|
// rotate the last n stack elements p times
|
||||||
roll: function PostScriptStack_roll(n, p) {
|
roll(n, p) {
|
||||||
var stack = this.stack;
|
var stack = this.stack;
|
||||||
var l = stack.length - n;
|
var l = stack.length - n;
|
||||||
var r = stack.length - 1,
|
var r = stack.length - 1,
|
||||||
@ -690,246 +694,245 @@ var PostScriptStack = (function PostScriptStackClosure() {
|
|||||||
stack[i] = stack[j];
|
stack[i] = stack[j];
|
||||||
stack[j] = t;
|
stack[j] = t;
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
return PostScriptStack;
|
return PostScriptStack;
|
||||||
})();
|
})();
|
||||||
var PostScriptEvaluator = (function PostScriptEvaluatorClosure() {
|
|
||||||
// eslint-disable-next-line no-shadow
|
class PostScriptEvaluator {
|
||||||
function PostScriptEvaluator(operators) {
|
constructor(operators) {
|
||||||
this.operators = operators;
|
this.operators = operators;
|
||||||
}
|
}
|
||||||
PostScriptEvaluator.prototype = {
|
|
||||||
execute: function PostScriptEvaluator_execute(initialStack) {
|
|
||||||
var stack = new PostScriptStack(initialStack);
|
|
||||||
var counter = 0;
|
|
||||||
var operators = this.operators;
|
|
||||||
var length = operators.length;
|
|
||||||
var operator, a, b;
|
|
||||||
while (counter < length) {
|
|
||||||
operator = operators[counter++];
|
|
||||||
if (typeof operator === "number") {
|
|
||||||
// Operator is really an operand and should be pushed to the stack.
|
|
||||||
stack.push(operator);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
switch (operator) {
|
|
||||||
// non standard ps operators
|
|
||||||
case "jz": // jump if false
|
|
||||||
b = stack.pop();
|
|
||||||
a = stack.pop();
|
|
||||||
if (!a) {
|
|
||||||
counter = b;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "j": // jump
|
|
||||||
a = stack.pop();
|
|
||||||
counter = a;
|
|
||||||
break;
|
|
||||||
|
|
||||||
// all ps operators in alphabetical order (excluding if/ifelse)
|
execute(initialStack) {
|
||||||
case "abs":
|
var stack = new PostScriptStack(initialStack);
|
||||||
a = stack.pop();
|
var counter = 0;
|
||||||
stack.push(Math.abs(a));
|
var operators = this.operators;
|
||||||
break;
|
var length = operators.length;
|
||||||
case "add":
|
var operator, a, b;
|
||||||
b = stack.pop();
|
while (counter < length) {
|
||||||
a = stack.pop();
|
operator = operators[counter++];
|
||||||
stack.push(a + b);
|
if (typeof operator === "number") {
|
||||||
break;
|
// Operator is really an operand and should be pushed to the stack.
|
||||||
case "and":
|
stack.push(operator);
|
||||||
b = stack.pop();
|
continue;
|
||||||
a = stack.pop();
|
|
||||||
if (isBool(a) && isBool(b)) {
|
|
||||||
stack.push(a && b);
|
|
||||||
} else {
|
|
||||||
stack.push(a & b);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "atan":
|
|
||||||
a = stack.pop();
|
|
||||||
stack.push(Math.atan(a));
|
|
||||||
break;
|
|
||||||
case "bitshift":
|
|
||||||
b = stack.pop();
|
|
||||||
a = stack.pop();
|
|
||||||
if (a > 0) {
|
|
||||||
stack.push(a << b);
|
|
||||||
} else {
|
|
||||||
stack.push(a >> b);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "ceiling":
|
|
||||||
a = stack.pop();
|
|
||||||
stack.push(Math.ceil(a));
|
|
||||||
break;
|
|
||||||
case "copy":
|
|
||||||
a = stack.pop();
|
|
||||||
stack.copy(a);
|
|
||||||
break;
|
|
||||||
case "cos":
|
|
||||||
a = stack.pop();
|
|
||||||
stack.push(Math.cos(a));
|
|
||||||
break;
|
|
||||||
case "cvi":
|
|
||||||
a = stack.pop() | 0;
|
|
||||||
stack.push(a);
|
|
||||||
break;
|
|
||||||
case "cvr":
|
|
||||||
// noop
|
|
||||||
break;
|
|
||||||
case "div":
|
|
||||||
b = stack.pop();
|
|
||||||
a = stack.pop();
|
|
||||||
stack.push(a / b);
|
|
||||||
break;
|
|
||||||
case "dup":
|
|
||||||
stack.copy(1);
|
|
||||||
break;
|
|
||||||
case "eq":
|
|
||||||
b = stack.pop();
|
|
||||||
a = stack.pop();
|
|
||||||
stack.push(a === b);
|
|
||||||
break;
|
|
||||||
case "exch":
|
|
||||||
stack.roll(2, 1);
|
|
||||||
break;
|
|
||||||
case "exp":
|
|
||||||
b = stack.pop();
|
|
||||||
a = stack.pop();
|
|
||||||
stack.push(a ** b);
|
|
||||||
break;
|
|
||||||
case "false":
|
|
||||||
stack.push(false);
|
|
||||||
break;
|
|
||||||
case "floor":
|
|
||||||
a = stack.pop();
|
|
||||||
stack.push(Math.floor(a));
|
|
||||||
break;
|
|
||||||
case "ge":
|
|
||||||
b = stack.pop();
|
|
||||||
a = stack.pop();
|
|
||||||
stack.push(a >= b);
|
|
||||||
break;
|
|
||||||
case "gt":
|
|
||||||
b = stack.pop();
|
|
||||||
a = stack.pop();
|
|
||||||
stack.push(a > b);
|
|
||||||
break;
|
|
||||||
case "idiv":
|
|
||||||
b = stack.pop();
|
|
||||||
a = stack.pop();
|
|
||||||
stack.push((a / b) | 0);
|
|
||||||
break;
|
|
||||||
case "index":
|
|
||||||
a = stack.pop();
|
|
||||||
stack.index(a);
|
|
||||||
break;
|
|
||||||
case "le":
|
|
||||||
b = stack.pop();
|
|
||||||
a = stack.pop();
|
|
||||||
stack.push(a <= b);
|
|
||||||
break;
|
|
||||||
case "ln":
|
|
||||||
a = stack.pop();
|
|
||||||
stack.push(Math.log(a));
|
|
||||||
break;
|
|
||||||
case "log":
|
|
||||||
a = stack.pop();
|
|
||||||
stack.push(Math.log(a) / Math.LN10);
|
|
||||||
break;
|
|
||||||
case "lt":
|
|
||||||
b = stack.pop();
|
|
||||||
a = stack.pop();
|
|
||||||
stack.push(a < b);
|
|
||||||
break;
|
|
||||||
case "mod":
|
|
||||||
b = stack.pop();
|
|
||||||
a = stack.pop();
|
|
||||||
stack.push(a % b);
|
|
||||||
break;
|
|
||||||
case "mul":
|
|
||||||
b = stack.pop();
|
|
||||||
a = stack.pop();
|
|
||||||
stack.push(a * b);
|
|
||||||
break;
|
|
||||||
case "ne":
|
|
||||||
b = stack.pop();
|
|
||||||
a = stack.pop();
|
|
||||||
stack.push(a !== b);
|
|
||||||
break;
|
|
||||||
case "neg":
|
|
||||||
a = stack.pop();
|
|
||||||
stack.push(-a);
|
|
||||||
break;
|
|
||||||
case "not":
|
|
||||||
a = stack.pop();
|
|
||||||
if (isBool(a)) {
|
|
||||||
stack.push(!a);
|
|
||||||
} else {
|
|
||||||
stack.push(~a);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "or":
|
|
||||||
b = stack.pop();
|
|
||||||
a = stack.pop();
|
|
||||||
if (isBool(a) && isBool(b)) {
|
|
||||||
stack.push(a || b);
|
|
||||||
} else {
|
|
||||||
stack.push(a | b);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "pop":
|
|
||||||
stack.pop();
|
|
||||||
break;
|
|
||||||
case "roll":
|
|
||||||
b = stack.pop();
|
|
||||||
a = stack.pop();
|
|
||||||
stack.roll(a, b);
|
|
||||||
break;
|
|
||||||
case "round":
|
|
||||||
a = stack.pop();
|
|
||||||
stack.push(Math.round(a));
|
|
||||||
break;
|
|
||||||
case "sin":
|
|
||||||
a = stack.pop();
|
|
||||||
stack.push(Math.sin(a));
|
|
||||||
break;
|
|
||||||
case "sqrt":
|
|
||||||
a = stack.pop();
|
|
||||||
stack.push(Math.sqrt(a));
|
|
||||||
break;
|
|
||||||
case "sub":
|
|
||||||
b = stack.pop();
|
|
||||||
a = stack.pop();
|
|
||||||
stack.push(a - b);
|
|
||||||
break;
|
|
||||||
case "true":
|
|
||||||
stack.push(true);
|
|
||||||
break;
|
|
||||||
case "truncate":
|
|
||||||
a = stack.pop();
|
|
||||||
a = a < 0 ? Math.ceil(a) : Math.floor(a);
|
|
||||||
stack.push(a);
|
|
||||||
break;
|
|
||||||
case "xor":
|
|
||||||
b = stack.pop();
|
|
||||||
a = stack.pop();
|
|
||||||
if (isBool(a) && isBool(b)) {
|
|
||||||
stack.push(a !== b);
|
|
||||||
} else {
|
|
||||||
stack.push(a ^ b);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new FormatError(`Unknown operator ${operator}`);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return stack.stack;
|
switch (operator) {
|
||||||
},
|
// non standard ps operators
|
||||||
};
|
case "jz": // jump if false
|
||||||
return PostScriptEvaluator;
|
b = stack.pop();
|
||||||
})();
|
a = stack.pop();
|
||||||
|
if (!a) {
|
||||||
|
counter = b;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "j": // jump
|
||||||
|
a = stack.pop();
|
||||||
|
counter = a;
|
||||||
|
break;
|
||||||
|
|
||||||
|
// all ps operators in alphabetical order (excluding if/ifelse)
|
||||||
|
case "abs":
|
||||||
|
a = stack.pop();
|
||||||
|
stack.push(Math.abs(a));
|
||||||
|
break;
|
||||||
|
case "add":
|
||||||
|
b = stack.pop();
|
||||||
|
a = stack.pop();
|
||||||
|
stack.push(a + b);
|
||||||
|
break;
|
||||||
|
case "and":
|
||||||
|
b = stack.pop();
|
||||||
|
a = stack.pop();
|
||||||
|
if (isBool(a) && isBool(b)) {
|
||||||
|
stack.push(a && b);
|
||||||
|
} else {
|
||||||
|
stack.push(a & b);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "atan":
|
||||||
|
a = stack.pop();
|
||||||
|
stack.push(Math.atan(a));
|
||||||
|
break;
|
||||||
|
case "bitshift":
|
||||||
|
b = stack.pop();
|
||||||
|
a = stack.pop();
|
||||||
|
if (a > 0) {
|
||||||
|
stack.push(a << b);
|
||||||
|
} else {
|
||||||
|
stack.push(a >> b);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "ceiling":
|
||||||
|
a = stack.pop();
|
||||||
|
stack.push(Math.ceil(a));
|
||||||
|
break;
|
||||||
|
case "copy":
|
||||||
|
a = stack.pop();
|
||||||
|
stack.copy(a);
|
||||||
|
break;
|
||||||
|
case "cos":
|
||||||
|
a = stack.pop();
|
||||||
|
stack.push(Math.cos(a));
|
||||||
|
break;
|
||||||
|
case "cvi":
|
||||||
|
a = stack.pop() | 0;
|
||||||
|
stack.push(a);
|
||||||
|
break;
|
||||||
|
case "cvr":
|
||||||
|
// noop
|
||||||
|
break;
|
||||||
|
case "div":
|
||||||
|
b = stack.pop();
|
||||||
|
a = stack.pop();
|
||||||
|
stack.push(a / b);
|
||||||
|
break;
|
||||||
|
case "dup":
|
||||||
|
stack.copy(1);
|
||||||
|
break;
|
||||||
|
case "eq":
|
||||||
|
b = stack.pop();
|
||||||
|
a = stack.pop();
|
||||||
|
stack.push(a === b);
|
||||||
|
break;
|
||||||
|
case "exch":
|
||||||
|
stack.roll(2, 1);
|
||||||
|
break;
|
||||||
|
case "exp":
|
||||||
|
b = stack.pop();
|
||||||
|
a = stack.pop();
|
||||||
|
stack.push(a ** b);
|
||||||
|
break;
|
||||||
|
case "false":
|
||||||
|
stack.push(false);
|
||||||
|
break;
|
||||||
|
case "floor":
|
||||||
|
a = stack.pop();
|
||||||
|
stack.push(Math.floor(a));
|
||||||
|
break;
|
||||||
|
case "ge":
|
||||||
|
b = stack.pop();
|
||||||
|
a = stack.pop();
|
||||||
|
stack.push(a >= b);
|
||||||
|
break;
|
||||||
|
case "gt":
|
||||||
|
b = stack.pop();
|
||||||
|
a = stack.pop();
|
||||||
|
stack.push(a > b);
|
||||||
|
break;
|
||||||
|
case "idiv":
|
||||||
|
b = stack.pop();
|
||||||
|
a = stack.pop();
|
||||||
|
stack.push((a / b) | 0);
|
||||||
|
break;
|
||||||
|
case "index":
|
||||||
|
a = stack.pop();
|
||||||
|
stack.index(a);
|
||||||
|
break;
|
||||||
|
case "le":
|
||||||
|
b = stack.pop();
|
||||||
|
a = stack.pop();
|
||||||
|
stack.push(a <= b);
|
||||||
|
break;
|
||||||
|
case "ln":
|
||||||
|
a = stack.pop();
|
||||||
|
stack.push(Math.log(a));
|
||||||
|
break;
|
||||||
|
case "log":
|
||||||
|
a = stack.pop();
|
||||||
|
stack.push(Math.log(a) / Math.LN10);
|
||||||
|
break;
|
||||||
|
case "lt":
|
||||||
|
b = stack.pop();
|
||||||
|
a = stack.pop();
|
||||||
|
stack.push(a < b);
|
||||||
|
break;
|
||||||
|
case "mod":
|
||||||
|
b = stack.pop();
|
||||||
|
a = stack.pop();
|
||||||
|
stack.push(a % b);
|
||||||
|
break;
|
||||||
|
case "mul":
|
||||||
|
b = stack.pop();
|
||||||
|
a = stack.pop();
|
||||||
|
stack.push(a * b);
|
||||||
|
break;
|
||||||
|
case "ne":
|
||||||
|
b = stack.pop();
|
||||||
|
a = stack.pop();
|
||||||
|
stack.push(a !== b);
|
||||||
|
break;
|
||||||
|
case "neg":
|
||||||
|
a = stack.pop();
|
||||||
|
stack.push(-a);
|
||||||
|
break;
|
||||||
|
case "not":
|
||||||
|
a = stack.pop();
|
||||||
|
if (isBool(a)) {
|
||||||
|
stack.push(!a);
|
||||||
|
} else {
|
||||||
|
stack.push(~a);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "or":
|
||||||
|
b = stack.pop();
|
||||||
|
a = stack.pop();
|
||||||
|
if (isBool(a) && isBool(b)) {
|
||||||
|
stack.push(a || b);
|
||||||
|
} else {
|
||||||
|
stack.push(a | b);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "pop":
|
||||||
|
stack.pop();
|
||||||
|
break;
|
||||||
|
case "roll":
|
||||||
|
b = stack.pop();
|
||||||
|
a = stack.pop();
|
||||||
|
stack.roll(a, b);
|
||||||
|
break;
|
||||||
|
case "round":
|
||||||
|
a = stack.pop();
|
||||||
|
stack.push(Math.round(a));
|
||||||
|
break;
|
||||||
|
case "sin":
|
||||||
|
a = stack.pop();
|
||||||
|
stack.push(Math.sin(a));
|
||||||
|
break;
|
||||||
|
case "sqrt":
|
||||||
|
a = stack.pop();
|
||||||
|
stack.push(Math.sqrt(a));
|
||||||
|
break;
|
||||||
|
case "sub":
|
||||||
|
b = stack.pop();
|
||||||
|
a = stack.pop();
|
||||||
|
stack.push(a - b);
|
||||||
|
break;
|
||||||
|
case "true":
|
||||||
|
stack.push(true);
|
||||||
|
break;
|
||||||
|
case "truncate":
|
||||||
|
a = stack.pop();
|
||||||
|
a = a < 0 ? Math.ceil(a) : Math.floor(a);
|
||||||
|
stack.push(a);
|
||||||
|
break;
|
||||||
|
case "xor":
|
||||||
|
b = stack.pop();
|
||||||
|
a = stack.pop();
|
||||||
|
if (isBool(a) && isBool(b)) {
|
||||||
|
stack.push(a !== b);
|
||||||
|
} else {
|
||||||
|
stack.push(a ^ b);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new FormatError(`Unknown operator ${operator}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return stack.stack;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Most of the PDFs functions consist of simple operations such as:
|
// Most of the PDFs functions consist of simple operations such as:
|
||||||
// roll, exch, sub, cvr, pop, index, dup, mul, if, gt, add.
|
// roll, exch, sub, cvr, pop, index, dup, mul, if, gt, add.
|
||||||
@ -938,84 +941,100 @@ var PostScriptEvaluator = (function PostScriptEvaluatorClosure() {
|
|||||||
// optimize some expressions using basic math properties. Keeping track of
|
// optimize some expressions using basic math properties. Keeping track of
|
||||||
// min/max values will allow us to avoid extra Math.min/Math.max calls.
|
// min/max values will allow us to avoid extra Math.min/Math.max calls.
|
||||||
var PostScriptCompiler = (function PostScriptCompilerClosure() {
|
var PostScriptCompiler = (function PostScriptCompilerClosure() {
|
||||||
function AstNode(type) {
|
class AstNode {
|
||||||
this.type = type;
|
constructor(type) {
|
||||||
}
|
this.type = type;
|
||||||
AstNode.prototype.visit = function (visitor) {
|
}
|
||||||
unreachable("abstract method");
|
|
||||||
};
|
|
||||||
|
|
||||||
function AstArgument(index, min, max) {
|
visit(visitor) {
|
||||||
AstNode.call(this, "args");
|
unreachable("abstract method");
|
||||||
this.index = index;
|
}
|
||||||
this.min = min;
|
|
||||||
this.max = max;
|
|
||||||
}
|
}
|
||||||
AstArgument.prototype = Object.create(AstNode.prototype);
|
|
||||||
AstArgument.prototype.visit = function (visitor) {
|
|
||||||
visitor.visitArgument(this);
|
|
||||||
};
|
|
||||||
|
|
||||||
function AstLiteral(number) {
|
class AstArgument extends AstNode {
|
||||||
AstNode.call(this, "literal");
|
constructor(index, min, max) {
|
||||||
this.number = number;
|
super("args");
|
||||||
this.min = number;
|
this.index = index;
|
||||||
this.max = number;
|
this.min = min;
|
||||||
}
|
this.max = max;
|
||||||
AstLiteral.prototype = Object.create(AstNode.prototype);
|
}
|
||||||
AstLiteral.prototype.visit = function (visitor) {
|
|
||||||
visitor.visitLiteral(this);
|
|
||||||
};
|
|
||||||
|
|
||||||
function AstBinaryOperation(op, arg1, arg2, min, max) {
|
visit(visitor) {
|
||||||
AstNode.call(this, "binary");
|
visitor.visitArgument(this);
|
||||||
this.op = op;
|
}
|
||||||
this.arg1 = arg1;
|
|
||||||
this.arg2 = arg2;
|
|
||||||
this.min = min;
|
|
||||||
this.max = max;
|
|
||||||
}
|
}
|
||||||
AstBinaryOperation.prototype = Object.create(AstNode.prototype);
|
|
||||||
AstBinaryOperation.prototype.visit = function (visitor) {
|
|
||||||
visitor.visitBinaryOperation(this);
|
|
||||||
};
|
|
||||||
|
|
||||||
function AstMin(arg, max) {
|
class AstLiteral extends AstNode {
|
||||||
AstNode.call(this, "max");
|
constructor(number) {
|
||||||
this.arg = arg;
|
super("literal");
|
||||||
this.min = arg.min;
|
this.number = number;
|
||||||
this.max = max;
|
this.min = number;
|
||||||
}
|
this.max = number;
|
||||||
AstMin.prototype = Object.create(AstNode.prototype);
|
}
|
||||||
AstMin.prototype.visit = function (visitor) {
|
|
||||||
visitor.visitMin(this);
|
|
||||||
};
|
|
||||||
|
|
||||||
function AstVariable(index, min, max) {
|
visit(visitor) {
|
||||||
AstNode.call(this, "var");
|
visitor.visitLiteral(this);
|
||||||
this.index = index;
|
}
|
||||||
this.min = min;
|
|
||||||
this.max = max;
|
|
||||||
}
|
}
|
||||||
AstVariable.prototype = Object.create(AstNode.prototype);
|
|
||||||
AstVariable.prototype.visit = function (visitor) {
|
|
||||||
visitor.visitVariable(this);
|
|
||||||
};
|
|
||||||
|
|
||||||
function AstVariableDefinition(variable, arg) {
|
class AstBinaryOperation extends AstNode {
|
||||||
AstNode.call(this, "definition");
|
constructor(op, arg1, arg2, min, max) {
|
||||||
this.variable = variable;
|
super("binary");
|
||||||
this.arg = arg;
|
this.op = op;
|
||||||
}
|
this.arg1 = arg1;
|
||||||
AstVariableDefinition.prototype = Object.create(AstNode.prototype);
|
this.arg2 = arg2;
|
||||||
AstVariableDefinition.prototype.visit = function (visitor) {
|
this.min = min;
|
||||||
visitor.visitVariableDefinition(this);
|
this.max = max;
|
||||||
};
|
}
|
||||||
|
|
||||||
function ExpressionBuilderVisitor() {
|
visit(visitor) {
|
||||||
this.parts = [];
|
visitor.visitBinaryOperation(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ExpressionBuilderVisitor.prototype = {
|
|
||||||
|
class AstMin extends AstNode {
|
||||||
|
constructor(arg, max) {
|
||||||
|
super("max");
|
||||||
|
this.arg = arg;
|
||||||
|
this.min = arg.min;
|
||||||
|
this.max = max;
|
||||||
|
}
|
||||||
|
|
||||||
|
visit(visitor) {
|
||||||
|
visitor.visitMin(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class AstVariable extends AstNode {
|
||||||
|
constructor(index, min, max) {
|
||||||
|
super("var");
|
||||||
|
this.index = index;
|
||||||
|
this.min = min;
|
||||||
|
this.max = max;
|
||||||
|
}
|
||||||
|
|
||||||
|
visit(visitor) {
|
||||||
|
visitor.visitVariable(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class AstVariableDefinition extends AstNode {
|
||||||
|
constructor(variable, arg) {
|
||||||
|
super("definition");
|
||||||
|
this.variable = variable;
|
||||||
|
this.arg = arg;
|
||||||
|
}
|
||||||
|
|
||||||
|
visit(visitor) {
|
||||||
|
visitor.visitVariableDefinition(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ExpressionBuilderVisitor {
|
||||||
|
constructor() {
|
||||||
|
this.parts = [];
|
||||||
|
}
|
||||||
|
|
||||||
visitArgument(arg) {
|
visitArgument(arg) {
|
||||||
this.parts.push(
|
this.parts.push(
|
||||||
"Math.max(",
|
"Math.max(",
|
||||||
@ -1026,36 +1045,42 @@ var PostScriptCompiler = (function PostScriptCompilerClosure() {
|
|||||||
arg.index,
|
arg.index,
|
||||||
"]))"
|
"]))"
|
||||||
);
|
);
|
||||||
},
|
}
|
||||||
|
|
||||||
visitVariable(variable) {
|
visitVariable(variable) {
|
||||||
this.parts.push("v", variable.index);
|
this.parts.push("v", variable.index);
|
||||||
},
|
}
|
||||||
|
|
||||||
visitLiteral(literal) {
|
visitLiteral(literal) {
|
||||||
this.parts.push(literal.number);
|
this.parts.push(literal.number);
|
||||||
},
|
}
|
||||||
|
|
||||||
visitBinaryOperation(operation) {
|
visitBinaryOperation(operation) {
|
||||||
this.parts.push("(");
|
this.parts.push("(");
|
||||||
operation.arg1.visit(this);
|
operation.arg1.visit(this);
|
||||||
this.parts.push(" ", operation.op, " ");
|
this.parts.push(" ", operation.op, " ");
|
||||||
operation.arg2.visit(this);
|
operation.arg2.visit(this);
|
||||||
this.parts.push(")");
|
this.parts.push(")");
|
||||||
},
|
}
|
||||||
|
|
||||||
visitVariableDefinition(definition) {
|
visitVariableDefinition(definition) {
|
||||||
this.parts.push("var ");
|
this.parts.push("var ");
|
||||||
definition.variable.visit(this);
|
definition.variable.visit(this);
|
||||||
this.parts.push(" = ");
|
this.parts.push(" = ");
|
||||||
definition.arg.visit(this);
|
definition.arg.visit(this);
|
||||||
this.parts.push(";");
|
this.parts.push(";");
|
||||||
},
|
}
|
||||||
|
|
||||||
visitMin(max) {
|
visitMin(max) {
|
||||||
this.parts.push("Math.min(");
|
this.parts.push("Math.min(");
|
||||||
max.arg.visit(this);
|
max.arg.visit(this);
|
||||||
this.parts.push(", ", max.max, ")");
|
this.parts.push(", ", max.max, ")");
|
||||||
},
|
}
|
||||||
|
|
||||||
toString() {
|
toString() {
|
||||||
return this.parts.join("");
|
return this.parts.join("");
|
||||||
},
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
function buildAddOperation(num1, num2) {
|
function buildAddOperation(num1, num2) {
|
||||||
if (num2.type === "literal" && num2.number === 0) {
|
if (num2.type === "literal" && num2.number === 0) {
|
||||||
@ -1156,9 +1181,8 @@ var PostScriptCompiler = (function PostScriptCompilerClosure() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// eslint-disable-next-line no-shadow
|
// eslint-disable-next-line no-shadow
|
||||||
function PostScriptCompiler() {}
|
class PostScriptCompiler {
|
||||||
PostScriptCompiler.prototype = {
|
compile(code, domain, range) {
|
||||||
compile: function PostScriptCompiler_compile(code, domain, range) {
|
|
||||||
var stack = [];
|
var stack = [];
|
||||||
var instructions = [];
|
var instructions = [];
|
||||||
var inputSize = domain.length >> 1,
|
var inputSize = domain.length >> 1,
|
||||||
@ -1337,8 +1361,8 @@ var PostScriptCompiler = (function PostScriptCompilerClosure() {
|
|||||||
result.push(out.join(""));
|
result.push(out.join(""));
|
||||||
});
|
});
|
||||||
return result.join("\n");
|
return result.join("\n");
|
||||||
},
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
return PostScriptCompiler;
|
return PostScriptCompiler;
|
||||||
})();
|
})();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user