Reworking the derivative function, removed assignement in parser.
The new derivative now supports executable elements.
This commit is contained in:
parent
ed4d30573c
commit
d991deee7b
4 changed files with 28 additions and 41 deletions
|
@ -42,7 +42,6 @@ Column {
|
|||
*/
|
||||
function openEditorDialog(obj) {
|
||||
// Open editor
|
||||
console.log(obj, obj.prototype)
|
||||
objectEditor.obj = obj
|
||||
objectEditor.objType = obj.type
|
||||
objectEditor.objIndex = Objects.currentObjects[obj.type].indexOf(obj)
|
||||
|
|
|
@ -1117,7 +1117,7 @@ ParserState.prototype.parseExpression = function (instr) {
|
|||
if (this.parseUntilEndStatement(instr, exprInstr)) {
|
||||
return;
|
||||
}
|
||||
this.parseVariableAssignmentExpression(exprInstr);
|
||||
this.parseConditionalExpression(exprInstr);
|
||||
if (this.parseUntilEndStatement(instr, exprInstr)) {
|
||||
return;
|
||||
}
|
||||
|
@ -1157,37 +1157,6 @@ ParserState.prototype.parseArrayList = function (instr) {
|
|||
return argCount;
|
||||
};
|
||||
|
||||
ParserState.prototype.parseVariableAssignmentExpression = function (instr) {
|
||||
this.parseConditionalExpression(instr);
|
||||
while (this.accept(TOP, '=')) {
|
||||
var varName = instr.pop();
|
||||
var varValue = [];
|
||||
var lastInstrIndex = instr.length - 1;
|
||||
if (varName.type === IFUNCALL) {
|
||||
if (!this.tokens.isOperatorEnabled('()=')) {
|
||||
throw new Error(qsTranslate('error', 'Function definition is not permitted.'));
|
||||
}
|
||||
for (var i = 0, len = varName.value + 1; i < len; i++) {
|
||||
var index = lastInstrIndex - i;
|
||||
if (instr[index].type === IVAR) {
|
||||
instr[index] = new Instruction(IVARNAME, instr[index].value);
|
||||
}
|
||||
}
|
||||
this.parseVariableAssignmentExpression(varValue);
|
||||
instr.push(new Instruction(IEXPR, varValue));
|
||||
instr.push(new Instruction(IFUNDEF, varName.value));
|
||||
continue;
|
||||
}
|
||||
if (varName.type !== IVAR && varName.type !== IMEMBER) {
|
||||
throw new Error(qsTranslate('error', 'Expected variable for assignment.'));
|
||||
}
|
||||
this.parseVariableAssignmentExpression(varValue);
|
||||
instr.push(new Instruction(IVARNAME, varName.value));
|
||||
instr.push(new Instruction(IEXPR, varValue));
|
||||
instr.push(binaryInstruction('='));
|
||||
}
|
||||
};
|
||||
|
||||
ParserState.prototype.parseConditionalExpression = function (instr) {
|
||||
this.parseOrExpression(instr);
|
||||
while (this.accept(TOP, '?')) {
|
||||
|
|
|
@ -22,8 +22,6 @@
|
|||
.import "../utils.js" as Utils
|
||||
.import "latex.js" as Latex
|
||||
|
||||
const DERIVATION_PRECISION = 0.1
|
||||
|
||||
var evalVariables = { // Variables not provided by expr-eval.js, needs to be provided manually
|
||||
"pi": Math.PI,
|
||||
"PI": Math.PI,
|
||||
|
@ -54,10 +52,27 @@ parser.functions.integral = function(a, b, f, variable) {
|
|||
return (b-a)/6*(f(a)+4*f((a+b)/2)+f(b))
|
||||
}
|
||||
|
||||
parser.functions.derivative = function(f, variable, x) {
|
||||
if(f == null || variable == null || x == null)
|
||||
throw EvalError("Usage: derivative(<function: string>, <variable: string>, <x: number>)")
|
||||
f = parser.parse(f).toJSFunction(variable, currentVars)
|
||||
return (f(x+DERIVATION_PRECISION/2)-f(x-DERIVATION_PRECISION/2))/DERIVATION_PRECISION
|
||||
parser.functions.derivative = function(...args) {
|
||||
let f, target, variable, x
|
||||
if(args.length == 2) {
|
||||
[f, x] = args
|
||||
if(typeof f != 'object' || !f.execute)
|
||||
throw EvalError(qsTranslate('usage', 'Usage: %1')
|
||||
.arg(qsTranslate('usage', 'derivative(<function: ExecutableObject>, <x: variable>)')))
|
||||
target = f
|
||||
f = (x) => target.execute(x)
|
||||
} else if(args.length == 3) {
|
||||
[f, variable, x] = args
|
||||
if(typeof f != 'string')
|
||||
throw EvalError(qsTranslate('usage', 'Usage: %1')
|
||||
.arg(qsTranslate('usage', 'derivative(<function: string>, <variable: string>, <x: variable>)')))
|
||||
f = parser.parse(f).toJSFunction(variable, currentVars)
|
||||
} else
|
||||
throw EvalError(qsTranslate('usage', 'Usage: %1 or\n%2')
|
||||
.arg(qsTranslate('usage', 'derivative(<function: string>, <variable: string>, <x: variable>)')
|
||||
.arg(qsTranslate('usage', 'derivative(<function: string>, <variable: string>, <x: variable>)'))))
|
||||
|
||||
let derivative_precision = x/10
|
||||
return (f(x+derivative_precision/2)-f(x-derivative_precision/2))/derivative_precision
|
||||
}
|
||||
|
||||
|
|
|
@ -71,9 +71,13 @@ function parif(elem, contents) {
|
|||
* @returns {string}
|
||||
*/
|
||||
function functionToLatex(f, args) {
|
||||
console.log("Generating latex", f, args)
|
||||
switch(f) {
|
||||
case "derivative":
|
||||
return '\\frac{d' + args[0].substr(1, args[0].length-2).replace(new RegExp(args[1].substr(1, args[1].length-2), 'g'), 'x') + '}{dx}';
|
||||
if(args.length == 3)
|
||||
return '\\frac{d' + args[0].substr(1, args[0].length-2).replace(new RegExp(args[1].substr(1, args[1].length-2), 'g'), 'x') + '}{dx}';
|
||||
else
|
||||
return '\\frac{d' + args[0] + '}{dx}';
|
||||
break;
|
||||
case "integral":
|
||||
return '\\int\\limits_{' + args[0] + '}^{' + args[1] + '}' + args[2].substr(1, args[2].length-2) + ' d' + args[3].substr(1, args[3].length-2);
|
||||
|
|
Loading…
Reference in a new issue