`

Lispy: Scheme Interpreter in Python

 
阅读更多
################ Lispy: Scheme Interpreter in Python

## (c) Peter Norvig, 2010-14; See http://norvig.com/lispy.html

################ Types

from __future__ import division

Symbol = str          # A Lisp Symbol is implemented as a Python str
List   = list         # A Lisp List is implemented as a Python list
Number = (int, float) # A Lisp Number is implemented as a Python int or float

################ Parsing: parse, tokenize, and read_from_tokens

def parse(program):
    "Read a Scheme expression from a string."
    return read_from_tokens(tokenize(program))

def tokenize(s):
    "Convert a string into a list of tokens."
    return s.replace('(',' ( ').replace(')',' ) ').split()

def read_from_tokens(tokens):
    "Read an expression from a sequence of tokens."
    if len(tokens) == 0:
        raise SyntaxError('unexpected EOF while reading')
    token = tokens.pop(0)
    if '(' == token:
        L = []
        while tokens[0] != ')':
            L.append(read_from_tokens(tokens))
        tokens.pop(0) # pop off ')'
        return L
    elif ')' == token:
        raise SyntaxError('unexpected )')
    else:
        return atom(token)

def atom(token):
    "Numbers become numbers; every other token is a symbol."
    try: return int(token)
    except ValueError:
        try: return float(token)
        except ValueError:
            return Symbol(token)

################ Environments

def standard_env():
    "An environment with some Scheme standard procedures."
    import math, operator as op
    env = Env()
    env.update(vars(math)) # sin, cos, sqrt, pi, ...
    env.update({
        '+':op.add, '-':op.sub, '*':op.mul, '/':op.div, 
        '>':op.gt, '<':op.lt, '>=':op.ge, '<=':op.le, '=':op.eq, 
        'abs':     abs,
        'append':  op.add,  
        'apply':   apply,
        'begin':   lambda *x: x[-1],
        'car':     lambda x: x[0],
        'cdr':     lambda x: x[1:], 
        'cons':    lambda x,y: [x] + y,
        'eq?':     op.is_, 
        'equal?':  op.eq, 
        'length':  len, 
        'list':    lambda *x: list(x), 
        'list?':   lambda x: isinstance(x,list), 
        'map':     map,
        'max':     max,
        'min':     min,
        'not':     op.not_,
        'null?':   lambda x: x == [], 
        'number?': lambda x: isinstance(x, Number),   
        'procedure?': callable,
        'round':   round,
        'symbol?': lambda x: isinstance(x, Symbol),
    })
    return env

class Env(dict):
    "An environment: a dict of {'var':val} pairs, with an outer Env."
    def __init__(self, parms=(), args=(), outer=None):
        self.update(zip(parms, args))
        self.outer = outer
    def find(self, var):
        "Find the innermost Env where var appears."
        return self if (var in self) else self.outer.find(var)

global_env = standard_env()

################ Interaction: A REPL

def repl(prompt='lis.py> '):
    "A prompt-read-eval-print loop."
    while True:
        val = eval(parse(raw_input(prompt)))
        if val is not None: 
            print(lispstr(val))

def lispstr(exp):
    "Convert a Python object back into a Lisp-readable string."
    if  isinstance(exp, list):
        return '(' + ' '.join(map(lispstr, exp)) + ')' 
    else:
        return str(exp)

################ Procedures

class Procedure(object):
    "A user-defined Scheme procedure."
    def __init__(self, parms, body, env):
        self.parms, self.body, self.env = parms, body, env
    def __call__(self, *args): 
        return eval(self.body, Env(self.parms, args, self.env))

################ eval

def eval(x, env=global_env):
    "Evaluate an expression in an environment."
    if isinstance(x, Symbol):      # variable reference
        return env.find(x)[x]
    elif not isinstance(x, List):  # constant literal
        return x                
    elif x[0] == 'quote':          # (quote exp)
        (_, exp) = x
        return exp
    elif x[0] == 'if':             # (if test conseq alt)
        (_, test, conseq, alt) = x
        exp = (conseq if eval(test, env) else alt)
        return eval(exp, env)
    elif x[0] == 'define':         # (define var exp)
        (_, var, exp) = x
        env[var] = eval(exp, env)
    elif x[0] == 'set!':           # (set! var exp)
        (_, var, exp) = x
        env.find(var)[var] = eval(exp, env)
    elif x[0] == 'lambda':         # (lambda (var...) body)
        (_, parms, body) = x
        return Procedure(parms, body, env)
    else:                          # (proc arg...)
        proc = eval(x[0], env)
        args = [eval(exp, env) for exp in x[1:]]
        return proc(*args)
分享到:
评论

相关推荐

    Lispy:Python编写的类似Lisp的语言

    使用python .\Lispy.py &lt;file&gt;.lpy [--debug]启动任何lispy文件,或使用python .\Lispy.py [--debug]启动解释器 享受 特征 基本数学运算符:+,-,*,/,//,% 基本逻辑运算符:=,!=,&lt;=,&gt; =,&lt;,&gt; 、! ...

    lispy:Python 中的实验性 Lisp 实现

    Lispy 是 Python 中的 Lisp 实现。 它受到 John McCarthy 的论文“符号表达式的递归函数及其机器计算,第一部分”的影响,可在找到; 通用 Lisp; Emacs Lisp 和 Clojure。 一些代码基于的 。 特征 完整功能列表...

    evil-lispy:使用Evil和Lispy进行精确的Lisp编辑

    例如,可以通过配置文件设置不同的键绑定,以便在不同的Lisp方言之间切换,如Common Lisp、Scheme或Racket。此外,`evil-lispy`还支持代码折叠,方便隐藏和显示复杂的代码结构。 为了充分利用`evil-lispy`,用户...

    lispy:简短而甜美的LISP编辑

    简短而甜美的LISP编辑 目录 [](#demo-1-practice-generating-codehttpabo-abogithubiolispydemo-1) [](#demo-2-的替换模型httpabo-abogithubiolispydemo-2) [](#demo-3-down-the-... lispy-down paredit-bac

    Lispy:一种基于Lisp并使用C编写的解释型,强类型化的函数式编程语言

    Lispy是一种解释性的,谐音的功能性编程语言,其灵感来自1958年的编程语言Lisp。 解释器使用MPC库用C编写,用于解析操作,当前可以用作交互式提示来实时评估表达式或评估用Lispy编写的外部文件。 与Lispy合作 通过...

    lispy:一个人可以用简单的家用物品制作各种Lisps。 如果一个人这么倾向于

    丽皮 “人们可以使用简单的家用物品制作各种Lips。 如果一个人这么倾向于。” 一个基于@orangeduck的小型Lisp(ish)解释器,基本支持整数,字符串,条件,用户定义的var和函数。 还没有宏和TCO,但是一个人可以...

    flpc:Forth Lisp Python连续体

    根据需要将您的代码设置为Forthy,Lispy或Pythonic。 较低的LoC数量(相对),可以轻松地根据需要修改启动顺序。 保存和加载状态(尚未实现的保存)。 [1]第一次,语法更改的描述当然必须用旧的Flpc编写。句法以下...

    lispy2js:JavaScript中的lispy2解释器

    参见:“(((甚至更好)Lisp)解释器(在Python中))” 它实现了除复数支持外的所有功能(如果需要,应易于添加)。 该代码可以作为“小语言”模块包含在您JavaScript应用程序中。 它可以通过bower安装,并...

    lispy-mnemonic:Lispy 的助记键绑定!

    lispy-mnemonic.el 这个包提供了一个次要模式,为设置键绑定。 lispy-mnemonic还广泛使用对相关命令进行分组并提高可发现性。 背景 lispy-mnemonic最初是为了让我更容易学习 Lispy。 我熟悉模态编辑的概念,但我...

    pypyscheme:公然剽窃 peter norvig 的 lispy 以测试 pypy 运行时

    这个项目可能受到了Peter Norvig的“lispy”代码的影响,Peter Norvig是一位知名的人工智能专家和编程语言设计师,他的“lispy”是用Python编写的一个小巧的Scheme解释器,常用于教学和演示目的。 描述中提到的...

    用Python编写一个简单的Lisp解释器的教程

    本文有两个目的: 一是讲述实现计算机语言解释器的通用方法,另外一点,着重展示如何使用Python来实现Lisp方言Scheme的一个子集。我将我的解释器称之为Lispy (lis.py)。几年前,我介绍过如何使用Java编写一个Scheme...

    LispyLite:一个基于Peter Norvig的lis.py Scheme解释器的玩具Scheme解释器和JavaScript编译器

    字符串,符号) 列表以外的任何数据结构任何实际的Scheme规范(例如R5RS或更高版本) 懒惰巨集主机语言互操作用法您可以使用以下命令从命令行进行编译: javac -d bin src/lispy/*您可以使用自己喜欢的IDE将源文件...

    lispy-arithmetic:用于执行受 lisp 启发的算术的 Javascript 库

    lispy-算术 一个小型 javascript 库,以受 lisp 启发的方式进行算术运算。 安装 npm install lispy-arithmetic 用法 var la = require ( 'lispy-arithmetic' ) ; la . add ( ) ; // 0 la . add ( 3 ) ; // 3 la . ...

    lispyscript:具有Lispy语法和宏的javascript

    具有Lispy语法和宏的Javascript! Lispyscript是使用“ Lispy”语法的Javascript,并编译为Javascript。 特征 Javscript语义学 巨集 尾叫优化 范本 回调序列(避免嵌套的回调) 莫纳德人 在浏览器中运行 服务器端...

    前端开源库-lispyscript

    1. **Lispy 语法**:Lispyscript 采用括号包围代码块的语法,这使得代码看起来更简洁且易于理解。它的语法结构清晰,代码层次分明,有助于提高代码的可读性和可维护性。 2. **宏系统**:宏是 Lisp 语言的一大特色,...

    clsh:一组用于运行和组成* nix进程的Lispy绑定

    Clsh是一组用于运行和组成* nix进程的Lispy绑定。 基本原理 Common Lisp令人惊叹,但不幸的是,有时我们没有所需的库。 通常,我们可以使用命令行工具来执行给定的任务。 例子 (in-package :clsh-user) (in-read...

    eazy-gnuplot:Super Duper Doopa Booka Lispy Gnuplot库

    Lispy Gnuplot库 无结构-无CFFI,无CLOS,无结构 只需将数据打印到plot功能中的*standard-output* 消息 支持带有多个:using选项的单个数据文件。 绘图使效率更高。 [2015年10月] 对Multiplot环境的支持部分可用。...

    awl:实验性的Lispy迷你语言

    锥子 Lisp :源自晚期英语awlyspian ,意为“至lisp”。 Awl是基于Lisp编程语言系列的实验性迷你语言。 概要 编写该手册的目的是为了娱乐和获利,以了解有关解释器设计,C语言编程以及使用转换为JavaScript的更多...

    lispyscript2:具有Lispy语法的ES6

    Lispyscript2 工作正在进行中。 不使用。

Global site tag (gtag.js) - Google Analytics