I have to make a Javascript version of the LET language and im making a test file. But each time i call a function its coming back undefined. There's an AST file, an interpreter file and finally my test file. There's also an Environment file but my test file for that works just fine.
Can any of you guys help me out and tell me why its returning undefined?
This is the test file for the AST.js/Interp.js files
var main = function(){
//console.log(valueOf(AST.DiffExp(5,3)))
var env1=Env.Env(null,null,null)
var env1=Env.extendEnv(env1, "x", 250);
console.log(AST.ConstExp(8))
}
//var modules = require('./modules.js');
var ConstExp = require('./Interp.js', './AST.js');
var AST=require('./AST.js', './Interp.js')
var valueOf=require('./Interp.js')
var Env= require("./Environment.js")
if(require.main === module) {
main();
}
This is the AST.js file
function ConstExp(i) {
this.Int = i;
}
function VarExp(id) {
this.Id = id;
}
function IsZeroExp (exp) {
this.Exp = exp;
}
function DiffExp (exp1, exp2) {
this.Exp1 = exp1;
this.Exp2 = exp2;
}
function IfExp (cond, cons, alt) {
this.Exp1 = cond; //Condition
this.Exp2 = cons; //Consequent
this.Exp3 = alt; //Alternative
}
//id is a strng not an expression
function LetExp (id, val, inExp) {
this.Id = id;
this.Exp1 = val
this.Exp2 = inExp
}
module.exports = {
ConstExp : ConstExp,
VarExp : VarExp,
IsZeroExp : IsZeroExp,
DiffExp : DiffExp,
IfExp : IfExp,
LetExp : LetExp
}
this is the Interpreter file (Interp.js)
function valueOf (e, p) {
switch(e.constructor){
case AST.ConstExp:
return Number(e.Int);
break;
case AST.VarExp:
return ENV.applyEnv(p, e.Id);
break;
case AST.IsZeroExp:
return valueOf(e.Exp, p) == 0;
break;
case AST.DiffExp:
return valueOf(e.Exp1, p) - valueOf(e.Exp2, p);
break;
case AST.LetExp:
var body = e.Exp2;
var v = valueOf(e.Exp1, p);
var pp = ENV.extendEnv(p, e.Id, v);
return valueOf(body, pp);
break;
case AST.IfExp:
if (valueOf(e.Exp1, p) == true){
return valueOf(e.Exp2, p);
} else {
return valueOf(e.Exp3, p);
}
break;
}
}
module.exports = {
valueOf: valueOf
}
AST = require("./AST.js");
ENV = require("./Environment.js");
Related
I have the following code that is not executing properly
platform.tsx
import { windowHelper } from "./windowHelper";
import { officeHelper } from "./officeHelper";
import { googleHelper } from "./googleHelper";
export class platformHelper {
static callFCT = (fnctname: any, fnctparams = null) => {
const platform = window.localStorage ? window.localStorage.getItem('platform') : "office";
var fn: any = null;
var wndhelper:any = new windowHelper();
var offhelper:any = new officeHelper();
var gghelper:any = new googleHelper();
switch (platform) {
case "window":
fn = wndhelper[fnctname];
break;
case "office":
fn = offhelper[fnctname];
console.log(fn); //return undefined
console.log(fnctname);
break;
case "google":
fn = gghelper[fnctname];
break;
default:
break;
}
// is object a function?
if (typeof fn === "function") fn.apply(null, fnctparams);
}
}
OfficeHelper.tsx
export class officeHelper {
constructor() { }
static GetEmail = () => {
return Office.context.mailbox.userProfile.emailAddress;
}
}
login.tsx
let userEmailAddress = platformHelper.callFCT("GetEmail");
console.log(userEmailAddress ) // UNDEFINED
The fn function is always undefined and the email address is not being returned as GetEmail is not being called
In your code, GetEmail is a static function of officeHelper class, so you have to access it through officeHelper.GetEmail (or officeHelper["GetEmail"]), instead of new officeHelper().GetEmail.
Then, as pointed out in the question comments and other answers, do not forget to return the result of fn.apply.
callFCT doesnt return value.
Add return in callFCT
// ...
if (typeof fn === "function") {
return fn(fnctparams)
};
// ...
You forget to return the content from the executed method. You should do:
static callFCT = (fnctname: any, fnctparams = null) => {
const platform = window.localStorage ? window.localStorage.getItem('platform') : "office";
var fn: any = null;
var wndhelper:any = new windowHelper();
var offhelper:any = new officeHelper();
var gghelper:any = new googleHelper();
switch (platform) {
case "window":
fn = wndhelper[fnctname];
break;
case "office":
fn = offhelper[fnctname];
console.log(fn); //return undefined
console.log(fnctname);
break;
case "google":
fn = gghelper[fnctname];
break;
default:
break;
}
if (typeof fn === "function")
return fn.apply(null, fnctparams); // return the result of GetEmail
return null; // no function -> return nothing
}
var dict = {
"configMigratedTo": {
"message": "Migrated configuration to configurator: $1"
}
}
var parametersForTranslation = {};
function __tr(src, params) {
parametersForTranslation[src] = params;
return buildMessage(src);
}
function buildMessage(src){
var message=dict[src] ? dict[src].message : src
console.log(message);
var messageArray = message.split("$");
var output = "";
messageArray.forEach(function(elem, index){
if(index === 0){
output += elem;
}else{
// get variable and index
var paramIndex = configMigratedTo.substring(0, 1);
var paramValue = parametersForTranslation[src][paramIndex-1];
output += paramValue;
output += configMigratedTo.substring(1);
}
});
return output;
}
__tr("configMigratedTo", [2]);
console.log(buildMessage("configMigratedTo"));
i want get result like __tr("configMigratedTo", [2]);
then it will give me
Migrated configuration to configurator: 2
i do not know where is wrong in my code
Try this one. Hope it helps!
var dict = {
"configMigratedTo": {
"message": "Migrated configuration to configurator: $1"
}
}
function __tr(src, params)
{
for (var key in dict)
{
if (key === src)
{
var message = dict[key].message;
return message.substring(0, message.length - 2) + params[0];
}
}
return;
}
console.log(__tr("configMigratedTo", [2]))
https://jsfiddle.net/eLd9u2pq/
Would that be enought?
var dict = {
"configMigratedTo": {
"message": "Migrated configuration to configurator: "
}
}
function buildMessage(src,param){
var output = dict[src].message + param;
return output;
}
console.log(buildMessage("configMigratedTo",2));
You are overcomplicating this, it's much easier using a regex and passing a function as replacer
var dict = {
"configMigratedTo": {
"message": "Migrated configuration to configurator: $1"
}
}
function __tr(src, params) {
if (! dict[src]) return src;
if (! /\$0/.test(dict[src].message)) params.unshift('');
return dict[src].message.replace(/\$(\d)+/g, (orig, match) => params[match] || orig);
}
console.log(__tr("configMigratedTo", [2]));
I am trying to write a memoization function, but keep getting the following error.
Error - "TypeError: getNthFibonacciNo is not a function
at dabebimaya.js:28:38
at https://static.jsbin.com/js/prod/runner-4.1.4.min.js:1:13924
at https://static.jsbin.com/js/prod/runner-4.1.4.min.js:1:10866"
How can I find this error in my code? I have tried googling the error with no avail. Please point out any additional errors too if possible.
function memoize(fn) {
var cache = {};
if (cache[arguments[0]]!==undefined) {
return cache[arguments[0]];
}
else {
var value = fn.apply(this, arguments);
cache[arguments[0]] = value;
return value;
}
}
var getNthFibonacciNo = memoize(function(n){
//1,1,2,3,5,8,13,21,34
if(i<=2)
return 1;
var fib = [0,1,1];
for(var i=3;i<=n;i++) {
fib[i] = fib[i-2]+fib[i-1];
}
return fib[n];
});
console.log(getNthFibonacciNo(7));
Your memoize function isn't returning a function.
function memoize(fn) {
var cache = {};
return function() {
if (cache[arguments[0]]!==undefined) {
return cache[arguments[0]];
}
else {
var value = fn.apply(this, arguments);
cache[arguments[0]] = value;
return value;
}
}
}
now returns a function so that it can be called multiple times.
Usage
function test(a) {
console.log('calling test', a);
return a + 1;
}
const memoized = memoize(test);
memoized(1); // prints calling test and returns 2
memoized(1); // returns 2
memoized(2); // prints calling test and returns 3
I managed to fix my code after suggestions by AnilRedshift. Below is the fixed code.
function memoize(fn) {
var cache = {};
return function() {
var key = JSON.stringify(arguments);
if (cache[key]) {
console.log('cache used');
return cache[key];
}
else {
var value = fn.apply(this, arguments);
cache[key] = value;
console.log('cache not used');
return value;
}
};
}
var fibonacciMemoized = memoize(function(n) {
//1,1,2,3,5,8,13,21,34
if(i<=2)
return 1;
var fib = [0,1,1];
for(var i=3;i<=n;i++) {
fib[i] = fibonacciMemoized(i-2)+fibonacciMemoized(i-1);
}
return fib[n];
});
console.log(fibonacciMemoized(7));
console.log(fibonacciMemoized(9));
I'm working through Cracking the Coding Interview and I thought I'd implement all the data structures in JS 5. Can anyone explain to me why my toString method isn't working?
Thanks!
function Node(data) {
this.next = null;
this.data = data;
}
Node.prototype.appendToTail = function(data) {
var end = new Node(data);
var n = this;
while (n.next != null) {
n = n.next;
}
n.next = end;
}
Node.prototype.toString = function(head) {
console.log(head)
if (head == null) {
return ""
} else {
return head.data.toString() + "-> " + head.next.toString();
}
}
var ll = new Node(1);
ll.appendToTail(3);
ll.appendToTail(4);
console.log(ll.toString())
function Node(data) {
this.next = null;
this.data = data;
}
Node.prototype.appendToTail = function(data) {
var end = new Node(data);
var n = this;
while (n.next != null) {
n = n.next;
}
n.next = end;
};
Node.prototype.toString = function() {
var returnValue = String(this.data);
if (this.next) {
returnValue = returnValue + "-> " + String(this.next);
}
return returnValue;
};
var ll = new Node(1);
ll.appendToTail(3);
ll.appendToTail(4);
console.log(String(ll))
or avoid this kind of problems completly and do not use prototype, class, this, call, etc
Your toString function takes an argument, but you're not passing it when you call toString.
If you want to access the node, you should use this, instead of passing in a value
Node.prototype.toString = function() {
var result = this.data.toString();
if (this.next) {
result += "-> " + this.next.toString();
}
return result;
}
How can i send parameter this to function.
Above options work in constructor :
selectors[i].onblur = this.validation;
But if in function Valid i call the selectors[i].validation, above solution will not working. Does Somebody know, how to call selectors[i].validation with parameter this??
For any help, i will be very grateful.
link to demo:
http://codepen.io/anon/pen/YqryVr
My js classes:
var Validator = (function () {
var errorClassName = "error";
var selectors;
var regexMap;
function Validator(id, regexObject) {
if (id === void 0) { id = "form"; }
regexMap = regexObject.getMap();
selectors = document.getElementById(id).elements;
for (i = 0; i < selectors.length; ++i) {
selectors[i].onblur = this.validation;
}
};
Validator.prototype.setErrorClassName = function (className) {
errorClassName = className;
};
Validator.prototype.addClass = function (selector) {
if(selector.className.indexOf(errorClassName) < 1)
selector.className += " " + errorClassName;
};
Validator.prototype.removeClass = function (selector) {
selector.className = selector.className.replace(errorClassName, '');
};
Validator.prototype.validation = function () {
alert('this.type: ' + this.type);
switch(this.type) {
case 'textarea':
case 'text':
if(this.dataset.regex in regexMap) this.dataset.regex = regexMap[this.dataset.regex];
var pattern = new RegExp(this.dataset.regex);
if(this.value.length !== 0 && pattern.test(this.value)) {
Validator.prototype.removeClass(this);
return true;
} else {
Validator.prototype.addClass(this);
return false;
}
break;
case 'select-one':
if(this.value.length === 0) {
Validator.prototype.addClass(this);
return false;
} else {
Validator.prototype.removeClass(this);
return true;
}
break;
}
return true;
};
Validator.prototype.valid = function () {
for (i = 0; i < selectors.length; ++i) {
selectors[i].validation;
}
return true;
};
return Validator;
}());
var SelectorAttribute = (function () {
function SelectorAttribute(name, regex) {
this.name = name;
this.regex = regex;
}
SelectorAttribute.prototype.toString = function () {
return "name: " + this.name + ", regex = " + this.regex;
};
return SelectorAttribute;
}());
var StandardRegexPatterns = (function () {
var map = {};
function StandardRegexPatterns() {
map['zip-code-poland'] = '^[0-9]{2}-[0-9]{3}$';
map['phone-number-poland'] = '^[0-9]{9}$';
map['digits'] = '^[0-9]+$';
map['alpha'] = '^[a-zA-z]+$';
map['email'] = '^[-a-z0-9~!$%^&*_=+}{\'?]+(\.[-a-z0-9~!$%^&*_=+}{\'?]+)*#([a-z0-9_][-a-z0-9_]*(\.[-a-z0-9_]+)*\.(aero|arpa|biz|com|coop|edu|gov|info|int|mil|museum|name|net|org|pro|travel|mobi|[a-z][a-z])|([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}))(:[0-9]{1,5})?';
map['login'] = '^[a-z0-9_-\.]{3,21}$';
map['ip-address'] = '^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$';
map['url-address'] = '^((http[s]?|ftp):\/)?\/?([^:\/\s]+)((\/\w+)*\/)([\w\-\.]+[^#?\s]+)(.*)?(#[\w\-]+)?$';
}
StandardRegexPatterns.prototype.getMap = function () {
return map;
};
return StandardRegexPatterns;
}());
$( document ).ready(function() {
var validator = new Validator('form', new StandardRegexPatterns());
validator.setErrorClassName("error");
//var pattern = new StandardRegexPatterns();
// alert(Object.keys(pattern.getMap()));
$("button").on('click', function(){
alert(validator.valid());
});
});
You can use the following:
functionname.apply(this, [arguments]);
or
functionname.call(this, argument1, argument2);
if you don't have arguments you can just omit them.
I usually just do this:
funcitonname.apply(this, Arguments);
if I'm calling this method from within a function already so I can carry on the arguments to the functionname().
Learn more about apply
Learn more about call