How do I parse an input string in Dart? - javascript

I want to parse an input mathematical string. How do I do it in Dart (with three.dart)?
Here is the js (three.js) version:
zFunc = Parser.parse(zFuncText).toJSFunction( ['x','y'] );
meshFunction = function(x, y)
{
x = xRange * x + xMin;
y = yRange * y + yMin;
var z = zFunc(x,y); //= Math.cos(x) * Math.sqrt(y);
if ( isNaN(z) )
return new THREE.Vector3(0,0,0); // TODO: better fix
else
return new THREE.Vector3(x, y, z);
};

in short : "is not as simple as in JS"
Explanation :
if i understand well your need, you want to be able to parse string expression like :
String math_square_expr = "(x) => pow(x, 2)"
some_magic_func(math_squre_expr)(5) // return 25
but it's possible in javascript, because you have some function like 'eval()' and others thing that make easy to transform string to code.
In Dart, you don't have this kind of function. the situation is more like with Java for this case.
You have 2 choice:
Build your own mathematical parser -> it's not cool, but if you need only little stuff it's possible
Use Js to do the job -> another solution is to use Javascript to create the function, but executed with dart. here a example :
import 'dart:js';
void main() {
String function = "var f = function(x, y) { return x*x + y; }";
JsObject functionJs = context.callMethod("eval", [function]);
print(functionJs);
print(context.callMethod("f", [5, 2]));
}
explanation:
String function = "var f = function(x, y) { return x*x + y; }";
First i create a variable named function to simulate user input, it need to be replace by a call or other thing to get user input.
Important thing: i create a javascript function that i store in a javascript variable. This will create a global javascript symbol named f.
JsObject functionJs = context.callMethod("eval", [function]);
Here i call a javascript function "eval" to dynamic evaluate the string previously create. after this operation my global JS context will contain a variable named f, with a function store in it.
print(context.callMethod("f", [5, 2]));
Know than my function is created and i can access on it, i call my function store in f, with my 2 parameters (x=5, y=2) and i display the result.
Note: becareful the to named of the JS variable that you will store your function. take a unused named.

Related

Replace (temporarlily) a function from JS file to one modified from the client browser

Suppose I have an Angular application that performs calculations between different parameters. The number of parameters can change, as well as the relations between.
To simplify, say users operates with 3 parameters fill-in A, B to obtain X and Y, having the formulas X = A + B and Y = A * X.
The application has one js file per calculated parameter. In that case A and B are filled in by user, and X and Y - calculated.
x.js
export function X(A: number, B: number): number {
return A + B;
}
y.js
export function Y(A: number, X: number): number {
return A * X;
}
The formulas are supposed to change over time. So I would like to let some special users to be able to modify the formula, and then preview/test the result.
A user could then load a js formula, modify it, and try it. In that mode, the function X() should not be loaded from the x.js file, but from the user modified text in editor.
My question is if there is a way to temporarily replace a JS function used by angular from a js file with some js code modified by user in the browser. That behavior should not affect other web application users.
It greatly depends on how you declare your functions.
But yes, it's possible.
All you need to have is a way to access your function. It must NOT be global (i.e. you have to call it with, for instance, window.myFunction).
Here is an example :
window.myFn = (a, b) => a + b;
console.log('Original function : ' + window.myFn(2, 3));
const symbol = window.myFn;
window.myFn = (a, b) => a * b;
console.log('Changed function : ' + window.myFn(2, 3));
window.myFn = (a, b, c) => symbol(a, b) * c;
console.log('Extended function : ' + window.myFn(2, 3, 4));
Note that you will have many context issues depending on how you wrote your functions, for instance in Angular, something like this
export class Component {
myFn() {}
}
Should be overwritten like this
export class Component {
constructor() { window.myFn = this.myFn.bind(this); }
myFn() {}
}

How can I call an individual Idris function from JavaScript?

Suppose I have a function in Idris that does some computation. For simplicity, let it be stringly typed for now.
f: String -> String
How can I compile this function to JavaScript so that it can then be called from any ordinary JavaScript code?
If that is too easy, suppose f, instead of String, deals with Double or even a custom Idris data type.
I know I can compile a whole module with a Main.main function and a more or less inscrutable blob of JavaScript will be output. Can I maybe extract my function from there by hand? How should I go about it?
P.S. Despite my answering myself, I am still looking for a better solution, so welcome.
Using this example, it seems at least with the Node backend this is doable. I've marked interact as export and added a library descriptor:
module Main
import Data.String
f: Double -> Double
f x = x + 1
export interact: String -> String
interact s = let x = parseDouble s in
case x of
Nothing => "NaN"
Just x => show (f x)
main: IO ()
main = do
s <- getLine
putStrLn (interact s)
lib : FFI_Export FFI_JS "" []
lib = Data String "String" $
Fun interact "interact" $
Fun main "main" $
End
I have then compiled with the --interface flag (this fails with --codegen javascript...):
idris --codegen node --interface --output ExportToJS.js ExportToJS.idr
and the resulting .js file has this at the end:
module.exports = {
interact: Main__interact,
main: Main__interact
};
}.call(this))
This should allow you to do require("./ExportToJavaScript.js").interact("42") from Node, and there is probably an equivalent to use from a browser.
Yes, you can extract any function by hand.
Build a module as follows:
module Main
import Data.String
f: Double -> Double
f x = x + 1
interact: String -> String
interact s = let x = parseDouble s in
case x of
Nothing => "NaN"
Just x => show (f x)
main: IO ()
main = do
s <- getLine
putStrLn (interact s)
Compile it as follows:
% idris --codegen javascript --output Main.js Main.idr
A file called Main.js will be created. There will be several megabytes of more or less inscrutable JavaScript code, just as you say.
Edit this file by hand and edit it similarly to this:
--- Resistors.js
+++ Resistors-default.js
## -1,7 +1,5 ##
"use strict";
-(function(){
-
const $JSRTS = {
throw: function (x) {
throw x;
## -36130,7 +36128,3 ##
}
}
}
-
-
-$_0_runMain();
-}.call(this))
Now notice this JS file has comments in it marking the JS functions with their Idris names. For instance, corresponding to our interact function there will be located this JS function:
// Main.interact
function Main__interact($_0_arg){
const $_1_in = Data__String__parseDouble($_0_arg);
if(($_1_in.type === 1)) {
const $cg$3 = Main__bestMatch_39_($_1_in.$1, Main__manyResistors_39_());
let $cg$2 = null;
$cg$2 = $cg$3.$1;
return Prelude__Show__Main___64_Prelude__Show__Show_36_Schema_58__33_show_58_0($cg$2);
} else {
return "NaN";
}
}
If you attach this JS file to a web page as a script, you may then open JS console in a browser and interact with your Idris functions, like this:
Main__interact("10")
"11"
Hope this helps!

Weird behavior when declaring class property with semicolon

class SomeClass {
x: 5;
y = 10;
}
const c = new SomeClass();
alert(c.x + ' : ' + c.y);
Why is the code compilable but the value of c.x is undefined?
What is the effect of declaring a class property with :?
Regarding the x: 5 part, although this is a valid javascript code, there is no much use for it.
This is a javascript label and it used (if any) mostly within loops context.
So to answer your questions:
Why is the code compilable
Because technically this is a valid javascript code (yet not a valid class field).
but the value of c.x is undefined
Because the x is a label and not a class field.
What is the effect of declaring a class property with :
You get a label instead of a class field.
Addendum
Another common mistake, is this code of block:
class SomeClass {
z = () => {
x: 5;
};
}
You would think that z() will return an object with an x key:
`{x:5}`
But actually you have a function with a label of x that just run an expression of 5.
Just for completeness sake, the fix will be either to add an explicit return and another set of curly braces
() => {return {x: 5}}
Or just wrap the whole thing with parentheses
() => ({x: 5})
Edit
As a followup to the comments below:
Just to be clear, your code compiles on several environments that i tested as well as stack-snippets as can be seen below:
class SomeClass {
x: 5;
y = 10;
}
const c = new SomeClass();
console.log(c.x + ' : ' + c.y);
The code is not valid ES6.
You seem to be "compiling" with babel, and have inadvertently enabled the flow syntax extension (and also class properties for the second line). In flow, x: 5 is a class field type annotation. Of course, 5 as a type doesn't make sense, but apparently they allow pretty arbitrary expressions.

Adding meta data to a primitive in javascript

Background
We have much of our data formatted like
var X = {value:'some val',error:'maybe an error',valid:true}
as a result we find ourselves calling X.value ALL the time.
We don't use the .error or .valid nearly as much, but we do use it.
What I want
To quit calling .value everywhere, but to still have access to meta data on a per data point level.
The Question
Is there one of
A) A way to put meta data on a primitive? attaching .error to an int for example? Is it possible for bools or strings?
B) A way to make a class that can be treated as a primitive, providing a specific data member when I do? IE X.value = 5, X+3 returns 8.
C) A better design for our data? Did we just lay this out wrong somehow?
You can set the method toString() to your object and return value.
var X = {
value: 1,
error:'maybe an error',
valid:true,
toString: function() {
return this.value;
}
}
X.value = 5;
console.log(X+3);
You can represent you data as a function object that also has properties:
var X = () => 1;
X.value = 1;
X.error = 'maybe an error';
X.valid = true,
console.log(X()); // 1
console.log(X.valid); // true
For better design you can encapsulate the creation of the data object in another function.

can someone explain this code in detail and how should I run it in my javascript program

In the code below, what is i and what is c? I want to use this code in my javascript so that I can move my map icon along a route.
How can I achieve this?
(function ()
{
if (!map.me)
{
map.me = map.createLocationMarker(
"http://libgmail.sourceforge.net/man.png", N.get("local"));
};
mv = function(i)
{
c = map.directions.polyline.getPoint(i);
map.recenterOrPanToLatLng(c);
map.setMarkerPosition(map.me, N.get("local"), c);
if (i < map.directions.polyline.numPoints - 1)
{
window.setTimeout("mv("+(i+1) + ")",750)
}
else
{
map.me.hide()
}
};
map.me.show();
mv(0)
}
)();
c is a co-ordinate and i is an indexer, both are coming from the outer scope to which this code belongs.
c - point in the map
i - integer parameter of function, that means number of point, starts with 0, every recursion loop increments by 1, ends by map.directions.polyline.numPoints - 1
This code shows the way across all points in map.directions.polyline

Categories

Resources