Example #1
0
def stdenv_defmacro_test():
    env = make_stdenv()
    called = 0
    def f(e):
        nonlocal called
        called += 1
        return SNode('num', 5)
    env.define('f', SNode('function', f))
    seval('(~defmacro twice (a) `(+ ,a ,a))', env)
    eq_(seval_strip('(~twice (f))', env), 10)
    eq_(called, 2)
Example #2
0
def make_stdenv():
    """Return an SEnvironment with builtins."""
    builtins = SEnvironment()
    builtins.define('+', _make_func(lambda *args: sum(args)))
    builtins.define('-', _make_func(operator.sub))
    builtins.define('*', _make_func(operator.mul))
    builtins.define('/', _make_func(operator.floordiv))
    builtins.define('%', _make_func(operator.mod))
    builtins.define('=', _make_func(operator.eq))
    builtins.define('/=', _make_func(operator.ne))
    builtins.define('<', _make_func(operator.lt))
    builtins.define('>', _make_func(operator.gt))
    builtins.define('<=', _make_func(operator.le))
    builtins.define('>=', _make_func(operator.ge))
    builtins.define('1-', _make_func(lambda x: x+1))
    builtins.define('1+', _make_func(lambda x: x-1))
    builtins.define('not', _make_func(operator.not_))
    builtins.define('read-int', _make_func(lambda: int(input(''))))
    builtins.define('print', SNode('function', _print))
    builtins.define('apply', SNode('function', _apply))
    builtins.define('list', _make_func(lambda *args: args))
    builtins.define('append', SNode('function', _append))
    builtins.define('cons', SNode('function', _cons))
    builtins.define('head', _make_func(lambda x: x[0]))
    builtins.define('tail', _make_func(lambda x: x[1:]))
    builtins.define('this-env', SNode('function', lambda env: SNode('env', env)))
    builtins.define('parent', SNode('function', lambda env, e: SNode('env',
        e.value.parent)))
    builtins.define('eval', SNode('function', _eval))
    builtins.define('nil', SNode('list', tuple()))
    builtins.define('#t', SNode('bool', True))
    builtins.define('#f', SNode('bool', False))
    builtins.define('if', SNode('function', _if))
    builtins.define('lambda', SNode('function', _lambda))
    builtins.define('define', SNode('function', _define))
    builtins.define('quote', SNode('function', _quote))
    builtins.define('quasiquote', SNode('function', _quasiquote))
    seval("""
        (~define defmacro
          (~lambda (name args . body)
            (eval `(~define ,name
                     (~lambda ,args
                       (eval ((~lambda () ,@body))
                             (parent (this-env)))))
                   (parent (this-env)))))
    """, builtins)
    seval("""
        (~defmacro defun (name args . body)
          `(~define ,name
            (~lambda ,args ,@body)))
    """, builtins)
    seval("""
        (~defmacro begin (. body)
          `((lambda () ,@body)))
    """, builtins)
    return builtins
Example #3
0
def fuzz_test_generator():
    program = sparse("""
    ((~lambda ()
      (~define x 10)
      (~define y 20)
      (~define z '(1 2 3))
      (~define li '(~ if (nil? '(2)) (add 4 5) (set! x 20)))
      (~defun add (x y) (+ x y))
      (add (~if (< x y) x y) x)))
    """)
    env = make_stdenv()
    env.define('a', sparse('10'))
    env.define('b', sparse('(4 5 6)'))
    env.define('c', sparse('(~define t 10)'))
    env.define('d', sparse('(+ 20 20)'))
    env.define('e', seval('(~lambda (x) (* x 2))', env))
    for i in range(FUZZ_TIMES):
        yield do_fuzz, random_modify(env, program), env
Example #4
0
def stdenv_defun_test():
    env = make_stdenv()
    seval('(~defun add (a b) (+ a b))', env)
    eq_(seval_strip('(add 1 2)', env), 3)
Example #5
0
 def seval(self, string):
     """Parse the given code and return the result."""
     return seval(string, self._env)