首页 > 其他分享 >怎样写一个解释器js版本

怎样写一个解释器js版本

时间:2022-11-21 00:00:53浏览次数:38  
标签:解释器 return 版本 interp list js env var calc

树遍历算法:

var treeSum = (list) => {

    if (typeof list === 'number') {
        return list;
    } else {
        var car = list.shift();
        var cdr = list.shift();
        return tree(car) + tree(cdr);
    } 
}

treeSum([1, 2]);
treeSum([1, [2, 3]]);
treeSum([[1, 2], 3]);
treeSum([[1, 2], [3, 4]]);

一个计算器

var calc = (list) => {
    if (typeof list === 'number') {
        return list;
    } else {
        var op = list.shift();
        var car = list.shift();
        var cdr = list.shift();

        if (op == '+') {
            return calc(car) + calc(cdr);
        } else if (op == '-') {
            return calc(car) - calc(cdr);
        } else if (op == '*') {
            return calc(car) * calc(cdr);
        } else {
            return calc(car) / calc(cdr);
        }
    }
}
calc(['+', 1, 2])

设置一个环境

var env0 = [];

var extenv = (x, v, env) => {
    var m = new Map();
    m.set(x, v);
    env.push(m);
    //如果需要进行查找需要做这样
}

var lookup = (x, env) => {
    var p = 0;
    for (var i in env) {
        if (env[i].has(x)) {
            p = env[i].get(x);
        }
    }
    if (p == undefined) {
        return false;
    } else {
        return p;
    }
}

下面是对语言环境的定义

var env0 = [];

var extenv = (x, v, env) => {
    var m = new Map();
    m.set(x, v);
    env.push(m);
}

var lookup = (x, env) => {
    var p = 0;
    for (var i in env) {
        if (env[i].has(x)) {
            p = env[i].get(x);
        }
    }
    if (p == undefined) {
        return false;
    } else {
        return p;
    }
}
#lang racket
;; 空环境
(define env0 '())

;; 对环境 env 进行扩展,把 x 映射到 v
(define ext-env
  (lambda (x v env)
    (cons `(,x . ,v) env)))

;; 取值。在环境中 env 中查找 x 的值
(define lookup
  (lambda (x env)
    (let ([p (assq x env)])
      (cond
       [(not p) #f]
       [else (cdr p)]))))

;;闭包的数据结构定义, 包含一个函数定义f和它定义时候所在的环境
(struct Closure (f env))

;;解释器
(define interp
  (lambda (exp env)
    (match exp
      [(? symbol? x)
       (let ([v (lookup x env)])
         (cond
           [(not v)
            (error "undefined varible" x)]
           [else v]))]
      [(? number? x) x]
      [`(lambda (,x) ,e)
       (Closure exp env)]
      [`(let ([,x ,e1]) ,e2)
       (let ([v1 (interp e1 env)])
         (interp e2 (ext-env x v1 env)))]
      [`(,e1, e2)
      (let ([v1 (interp e1 env)]                ;;计算函数e1的值
            [v2 (interp e2 env)])               ;;计算参数e2的值
        (match v1
          [(Closure `(lambda (,x) ,e) env-save) ;;使用模式匹配的方式取出闭包中的各个子结构
           (interp e (ext-env x v2 env-save))]))];;在闭包的环境中env-save中把x绑定到v2, 解释函数体
      [`(,op ,e1, e2)
       (let ([v1 (interp e1 env)]
             [v2 (interp e2 env)])
         (match op
           ['+ (+ v1 v2)]
           ['- (- v1 v2)]
           ['* (* v1 v2)]
           ['/ (/ v1 v2)]))])))

(define r2
  (lambda (exp)
    (interp exp env0)))

;;scheme中的作用域
(let ([x 2])
  (let ([f (lambda (y) (* x y))])
    (let ([x 4])
      (f 3)))) ;;在这里不应该去产生影响

;;对函数调用的解释
(r2 '(+ 1 2))
(r2 '(* 2 3))
(r2 '((lambda (x))))

标签:解释器,return,版本,interp,list,js,env,var,calc
From: https://www.cnblogs.com/zhengel/p/16907371.html

相关文章

  • HTML、CSS、JS实现的HTML、CSS、JS编辑器
    Atom通用代码编辑器,Github出品,基于electron​桌面应用平台,https://atom.io/,源代码:https://github.com/atom/atomVisualStudioCode通用代码编辑器,微软出品,基于electron​......
  • JSP以及MVC模式和三层架构
    jsp:javaserverpages,java服务端页面。它是一种,动态网页技术,其中可以定义html等静态内容,也可以定义java代码等动态内容,可以避免在servlet中用write()直接输出html,但是本质......
  • C语言标准ISO9899的各个版本
    C90ISO/IEC9899:1990219PagesISO/IEC9899:1990/AMD1:199551PagesISO/IEC9899:1990/COR1:19948PagesISO/IEC9899:1990/COR2:19961PagesC99ISO/IEC9899:......
  • JS循环
    js循环内容回顾程序的执行结构分支结构:if,switch本章内容while,do...while循环for循环break,continue关键字第一节while循环和do...while循环1.while循环......
  • 安装SQL Server 2016出错提示:需要安装oracle JRE7 更新 51(64位)或更高版本问题的解决
    这篇文章主要介绍了安装SQLServer2016出错提示:需要安装oracleJRE7更新51(64位)或更高版本问题的解决方法,需要的朋友可以参考下 错误提示原因:安装时检测出电脑没有......
  • JS比较数值大小
    一、简单循环算法代码如下:constnumbers=[5,6,2,3,7];letmax=-Infinity;for(leti=0;i<numbers.length;i++){if(numbers[i]>max)max......
  • centos8 安装php7.4以上版本
    前面找到php因为某些软件对应的不同的版本,前面安装过忘记了后,然后有些忘记了特意记录一下遇见的一些问题 因为没有官方维护的源需要切换源才能进行安装;Centos8(Liu......
  • JSON
    1、概念:JavaScriptObjectNotation,JavaScript对象表示法。2、优点:由于其语法简单,层次结构鲜明,现多用于作为数据载体,在网络中进行数据传输。3、JSON基础语法  4、......
  • pnpm 版本切换
    pnpm如何做版本管理?有时候一个项目需要用pnpm6,另一个项目可能要用pnpm7方法一pnpmdlxpnpm@7installpnpmdlxpnpm@7rundev:all即用pnpmdlxpnpm@7来指定用......
  • js(变量名提升)
    问:1.什么叫变量名提升答:在js里var和function声明的变量或者函数可以在我们声明之前去使用他们,这种现象就叫变量名提升。 问:2.提升的原理是什么答:js会把代码分为可......