在javascript中处理lisp解释器时出现TypeError

时间:2022-09-29 17:07:01

i tried to make a simple and basic lisp interpreter using JavaScript. First of all am new to js, and i cleared most of the errors in the code myself.But i can't clear the TypeError occured in this code.I tried, and i ain't get a better way to solve.Do guys please help me to solve this,Am not the best in js,myself just a beginner.If any one knows,help me

我试图使用JavaScript创建一个简单而基本的lisp解释器。首先是js的新手,我自己清除了代码中的大部分错误。但我无法清除此代码中出现的TypeError。我试过,我没有得到更好的解决方法。请帮助我解决这个问题,我不是最好的js,我自己只是一个初学者。如果有人知道,请帮助我

//Parsing part.......
function parse(program) {
    return read_from_tokens(tokenize(program));
}

function tokenize(program) {
    return program.replace(/\(/g, ' ( ').replace(/\)/g, ' )  ').replace(/^\s+|\s+$/g, '').split(/\s+/g);
}

function read_from_tokens(tokens) {
    if (!tokens.length)
        throw new SyntaxError('unexpected EOF while reading');
    var token = tokens.shift();
    if ('(' === token) {
        var l = [];
        while (tokens[0] !== ')') {
            l.push(read_from_tokens(tokens));
        }
        tokens.shift(); // ')'
        return l;
    } else if (')' === token) {
        throw new SyntaxError('unexpected )');
    } else {
        return atom(token);
    }
}

function atom(token) {
    var number = Number(token);
    if (!isNaN(number) || token === 'NaN')
        return number;
    return String(token);
}

//interpret....

function Env(parms, args, outer) {
    this.outer = outer; 
    this.dict = Object.create(null);
    this.get = function(k){
        return this.dict[k];
    };
    this.set = function(k, val){
        this.dict[k] = val;
    };
    this.find = function(k){
        if((k) in this.dict)
            return this;
        return this.outer ? this.outer.find(k) : null;
    };

    if (parms && args) {
        for(var i = 0; i<parms.length; ++i)
            this.set(parms[i], args[i]);
    }
}

var global_env = new Env();
var std_env = {
    '+' : function(a,b){return a+b;},
    '-' : function(a,b){return a-b;},
    '*' : function(a,b){return a*b;},
    '/' : function(a,b){return a/b;},
    '>' : function(a,b){return a > b;},
    '<' : function(a,b){return a < b;},
    '>=' : function(a,b){return a >= b;},
    '<=' : function(a,b){return a <= b;},
    '=' : function(a,b){return a==b;},
    'and' : function(a,b){return a && b;},
    'or' : function(a,b){return a || b;},
    'not' : function(a){return !a;},
    'equal?' : function(a,b){return a === b;},
    'eq?' : function(a,b){return a === b},
    'length' : function(a){return a.length;},
    'cons' : function(a,b){return [a].concat(b);},
    'car' : function(a){return a[0];},
    'cdr' : function(a){return a.slice(1);},
    'append' : function(a,b){return a.concat(b);},
    'list' : function(){return [].slice.call(arguments);},
    'list?' : function(a){return Array.isArray(a);},
    'null?' : function(a){return Array.isArray(a) && !a.length;},
    'symbol?' : function(a){return typeof a === 'string';}
};
Object.keys(std_env).forEach(function(key){
    global_env.set(key, std_env[key]);
});

['abs', 'ceil', 'cos', 'exp', 'floor', 'log', 'max', 'min',
 'pow', 'random', 'round', 'sin', 'sqrt', 'tan'].forEach(function(n){
    global_env.set(n, Math[n]);
});

function check(t) {return Array.isArray(t) ? t.length : t;}

function eval1(x, env){
    env = global_env;
    if (typeof x === 'string')
        return env.find(x).get(x);
    if (!Array.isArray(x))
        return x
    if (x[0] === 'quote')
        return x[1];
    if (x[0] === 'if')  //if test conseq alt
        return eval1(check(eval1(x[1], env)) ? x[2] : x[3], env);
    if (x[0] === 'set!')
        return env.find(x[1]).set(x[1], eval1(x[1], env));
    if (x[0] === 'define')
         return env.set(x[1], eval1(x[2], env))
    if (x[0] == 'lambda')
        return function(){return eval1(x[2], new Env(x[1], arguments, env));};

    var exps = x.map(function(exp){return eval1(exp, env);});
    var proc = exps.shift()
    return proc.apply(null, exps)
}
//var repl = require('repl');

//var rl = repl.createInterface({
//    input : process.stdin,
//    output : process.stdout
//});
process.stdout.write("user> ");
process.stdin.setEncoding('utf8');
process.stdin.once('data', function repl(){
    while (true){
//      prompt : "lis >"
        var val = eval1(parse(("lis >")));
        return val === undefined ? undefined : schemestr(val);
    }
}).resume();

function schemestr(exp){
    if (Array.isArray(exp))
        return '(' + exp.map(schemstr).join(' ' ) + ')';
    String(exp)
}

the error message is shown below, pass your knowledge

错误信息如下所示,传递您的知识

user> (define circle-area (lambda (r) (* pi (* r r))))

/home/sonu/python/lisp/jss.js:98
        return env.find(x).get(x);
                   ^
TypeError: Cannot call method 'get' of null
    at eval1 (/home/sonu/python/lisp/jss.js:98:21)
    at ReadStream.repl (/home/sonu/python/lisp/jss.js:127:19)
    at ReadStream.g (events.js:180:16)
    at ReadStream.EventEmitter.emit (events.js:95:17)
    at ReadStream.<anonymous> (_stream_readable.js:746:14)
    at ReadStream.EventEmitter.emit (events.js:92:17)
    at emitReadable_ (_stream_readable.js:408:10)
    at emitReadable (_stream_readable.js:404:5)
    at readableAddChunk (_stream_readable.js:165:9)

1 个解决方案

#1


0  

you can use env.find(x) or env.get(x), but you can't use env.find(x).get(x) because there is not method get(x) in method find(x)

您可以使用env.find(x)或env.get(x),但不能使用env.find(x).get(x),因为方法find(x)中没有方法get(x)

#1


0  

you can use env.find(x) or env.get(x), but you can't use env.find(x).get(x) because there is not method get(x) in method find(x)

您可以使用env.find(x)或env.get(x),但不能使用env.find(x).get(x),因为方法find(x)中没有方法get(x)