git @ Cat's Eye Technologies Tamsin / master src / tamsin / sysmod.py
master

Tree @master (Download .tar.gz)

sysmod.py @masterraw · history · blame

# encoding: UTF-8

# Copyright (c)2014 Chris Pressey, Cat's Eye Technologies.
# Distributed under a BSD-style license; see LICENSE for more information.

# Python version of Tamsin's $ module.

import sys

from tamsin.term import Atom, Constructor
from tamsin.scanner import EOF


TRANSLATOR = {'return': 'return_', 'print': 'print_'}


def call(name, interpreter, args):
    name = TRANSLATOR.get(name, name)
    if name not in globals():
        raise NotImplementedError(name)
    return globals()[name](interpreter, args)


def arity(name):
    name = TRANSLATOR.get(name, name)
    if name not in globals():
        raise NotImplementedError(name)
    return globals()[name].arity


def return_(self, args):
    return (True, args[0])
return_.arity = 1


def fail(self, args):
    return (False, args[0])
fail.arity = 1


def expect(self, args):
    upcoming_token = self.scanner.peek()
    term = args[0]
    token = str(term)
    if self.scanner.consume(token):
        return (True, term)
    else:
        return (False,
            Atom(self.scanner.error_message("'%s'" % token, upcoming_token))
        )
expect.arity = 1


def eof(self, args):
    if self.scanner.peek() is EOF:
        return (True, '')
    else:
        return (False,
            Atom(self.scanner.error_message('EOF', self.scanner.peek()))
        )
eof.arity = 0


def any(self, args):
    if self.scanner.peek() is not EOF:
        return (True, Atom(self.scanner.scan()))
    else:
        return (False,
            Atom(self.scanner.error_message('any token', EOF))
        )
any.arity = 0


def alnum(self, args):
    if (self.scanner.peek() is not EOF and
        self.scanner.peek()[0].isalnum()):
        return (True, Atom(self.scanner.scan()))
    else:
        return (False,
            Atom(self.scanner.error_message('alphanumeric', self.scanner.peek()))
        )
alnum.arity = 0


def upper(self, args):
    if (self.scanner.peek() is not EOF and
        self.scanner.peek()[0].isupper()):
        return (True, Atom(self.scanner.scan()))
    else:
        return (False,
            Atom(self.scanner.error_message('uppercase', self.scanner.peek()))
        )
upper.arity = 0


def startswith(self, args):
    if (self.scanner.peek() is not EOF and
        self.scanner.peek()[0].startswith((str(args[0]),))):
        return (True, Atom(self.scanner.scan()))
    else:
        return (False,
            Atom(self.scanner.error_message("'%s...'" % args[0], self.scanner.peek()))
        )
startswith.arity = 1


def equal(self, args):
    if args[0].match(args[1]) != False:
        return (True, args[0])
    else:
        return (False, Atom("term '%s' does not equal '%s'" %
                            (args[0], args[1])))
equal.arity = 2


def unquote(self, args):
    q = str(args[0])
    l = str(args[1])
    r = str(args[2])
    if (q.startswith(l) and q.endswith(r)):
        if len(r) == 0:
            return (True, Atom(q[len(l):]))
        return (True, Atom(q[len(l):-len(r)]))
    else:
        return (False, Atom("term '%s' is not quoted with '%s' and '%s'" %
                            (q, l, r)))
unquote.arity = 3


def mkterm(self, args):
    t = args[0]
    l = args[1]
    contents = []
    while isinstance(l, Constructor) and l.tag == 'list':
        contents.append(l.contents[0])
        l = l.contents[1]
    if contents:
        return (True, Constructor(t.text, contents))
    else:
        return (True, t)
mkterm.arity = 2


def reverse(self, args):
    return (True, args[0].reversed(args[1]))
reverse.arity = 2


def print_(self, args):
    val = args[0]
    sys.stdout.write(str(val))
    sys.stdout.write("\n")
    return (True, val)
print_.arity = 1


def emit(self, args):
    val = args[0]
    sys.stdout.write(str(val))
    return (True, val)
emit.arity = 1


def repr(self, args):
    val = args[0]
    val = Atom(val.repr())
    return (True, val)
repr.arity = 1


counter = 0

def gensym(self, args):
    global counter
    counter += 1
    return (True, Atom(str(args[0]) + str(counter)))
gensym.arity = 1


def hexbyte(self, args):
    return (True, Atom(chr(int(args[0].text + args[1].text, 16))))
hexbyte.arity = 2


def format_octal(self, args):
    return (True, Atom("%o" % ord(args[0].text[0])))
format_octal.arity = 1


def length(self, args):
    return (True, Atom(str(len(str(args[0])))))
length.arity = 1