Esempio n. 1
0
def concat(args):
    new_lst = []
    for l in args.values:
        if not isinstance(l, MalList):
            throw_str("concat called with non-list/non-vector")
        new_lst = new_lst + l.values
    return MalList(new_lst)
Esempio n. 2
0
def read_atom(reader):
    if IS_RPYTHON:
        int_re = '-?[0-9]+$'
        float_re = '-?[0-9][0-9.]*$'
    else:
        int_re = re.compile('-?[0-9]+$')
        float_re = re.compile('-?[0-9][0-9.]*$')
    token = reader.next()
    if re.match(int_re, token):     return MalInt(int(token))
##    elif re.match(float_re, token): return int(token)
    elif token[0] == '"':
        end = len(token)-1
        if end == 1:
            return MalStr(u"")
        elif end < 1 or token[end] != '"':
            types.throw_str("expected '\"', got EOF")
        else:
            s = unicode(token[1:end])
            s = types._replace(u'\\\\',   u"\u029e", s)
            s = types._replace(u'\\"',    u'"', s)
            s = types._replace(u'\\n',    u"\n", s)
            s = types._replace(u"\u029e", u"\\", s)
            return MalStr(s)
    elif token[0] == ':':           return _keywordu(unicode(token[1:]))
    elif token == "nil":            return types.nil
    elif token == "true":           return types.true
    elif token == "false":          return types.false
    else:                           return MalSym(unicode(token))
Esempio n. 3
0
def divide(args):
    a, b = args[0], args[1]
    if not isinstance(a, MalInt) or not isinstance(b, MalInt):
        throw_str("/ called on non-integer")
    if b.value == 0:
        throw_str("divide by zero")
    return MalInt(int(a.value/b.value))
Esempio n. 4
0
def apply(args):
    f, fargs = args[0], args.rest()
    last_arg = fargs.values[-1]
    if not isinstance(last_arg, MalList):
        throw_str("map called with non-list")
    all_args = fargs.values[0:-1] + last_arg.values
    return f.apply(MalList(all_args))
Esempio n. 5
0
def empty_Q(args):
    seq = args[0]
    if isinstance(seq, MalList):
        return wrap_tf(len(seq) == 0)
    elif seq is nil:
        return true
    else:
        throw_str("empty? called on non-sequence")
Esempio n. 6
0
def symbol(args):
    a0 = args[0]
    if isinstance(a0, MalStr):
        return types._symbol(a0.value)
    elif isinstance(a0, MalSym):
        return a0
    else:
        throw_str("symbol called on non-string/non-symbol")
Esempio n. 7
0
def rest(args):
    a0 = args[0]
    if a0 is nil:
        return MalList([])
    elif not isinstance(a0, MalList):
        throw_str("rest called with non-list/non-vector")
    if len(a0) == 0: return MalList([])
    else:            return a0.rest()
Esempio n. 8
0
def first(args):
    a0 = args[0]
    if a0 is nil:
        return nil
    elif not isinstance(a0, MalList):
        throw_str("first called with non-list/non-vector")
    if len(a0) == 0: return nil
    else:            return a0[0]
Esempio n. 9
0
def mapf(args):
    f, lst = args[0], args[1]
    if not isinstance(lst, MalList):
        throw_str("map called with non-list")
    res = []
    for a in lst.values:
        res.append(f.apply(MalList([a])))
    return MalList(res)
Esempio n. 10
0
def count(args):
    seq = args[0]
    if isinstance(seq, MalList):
        return MalInt(len(seq))
    elif seq is nil:
        return MalInt(0)
    else:
        throw_str("count called on non-sequence")
Esempio n. 11
0
def with_meta(args):
    obj, meta = args[0], args[1]
    if isinstance(obj, MalMeta):
        new_obj = types._clone(obj)
        new_obj.meta = meta
        return new_obj
    else:
        throw_str("with-meta not supported on type")
Esempio n. 12
0
def do_readline(args):
    prompt = args[0]
    if not isinstance(prompt, MalStr):
        throw_str("readline prompt is not a string")
    try:
        return MalStr(unicode(mal_readline.readline(str(prompt.value))))
    except EOFError:
        return nil
Esempio n. 13
0
def swap_BANG(args):
    atm, f, fargs = args[0], args[1], args.slice(2)
    if not isinstance(atm, MalAtom):
        throw_str("swap! called on non-atom")
    if not isinstance(f, MalFunc):
        throw_str("swap! called with non-function")
    all_args = [atm.value] + fargs.values
    atm.value = f.apply(MalList(all_args))
    return atm.value
Esempio n. 14
0
def dissoc(args):
    src_hm, keys = args[0], args.rest()
    new_dct = src_hm.dct.copy()
    for k in keys.values:
        if not isinstance(k, MalStr):
            throw_str("dissoc called with non-string/non-keyword key")
        if k.value in new_dct:
            del new_dct[k.value]
    return MalHashMap(new_dct)
Esempio n. 15
0
def assoc(args):
    src_hm, key_vals = args[0], args.rest()
    new_dct = src_hm.dct.copy()
    for i in range(0,len(key_vals),2):
        k = key_vals[i]
        if not isinstance(k, MalStr):
            throw_str("assoc called with non-string/non-keyword key")
        new_dct[k.value] = key_vals[i+1]
    return MalHashMap(new_dct)
Esempio n. 16
0
def read_sequence(reader, start='(', end=')'):
    ast = []
    token = reader.next()
    if token != start: types.throw_str("expected '" + start + "'")

    token = reader.peek()
    while token != end:
        if not token: types.throw_str("expected '" + end + "', got EOF")
        ast.append(read_form(reader))
        token = reader.peek()
    reader.next()
    return ast
Esempio n. 17
0
def read_sequence(reader, start='(', end=')'):
    ast = []
    token = reader.next()
    if token != start: types.throw_str("expected '" + start + "'")

    token = reader.peek()
    while token != end:
        if not token: types.throw_str("expected '" + end + "', got EOF")
        ast.append(read_form(reader))
        token = reader.peek()
    reader.next()
    return ast
Esempio n. 18
0
def conj(args):
    lst, args = args[0], args.rest()
    new_lst = None
    if types._list_Q(lst):
        vals = args.values[:]
        vals.reverse()
        new_lst = MalList(vals + lst.values)
    elif types._vector_Q(lst):
        new_lst = MalVector(lst.values + list(args.values))
    else:
        throw_str("conj on non-list/non-vector")
    new_lst.meta = lst.meta
    return new_lst
Esempio n. 19
0
def seq(args):
    a0 = args[0]
    if isinstance(a0, MalVector):
        if len(a0) == 0: return nil
        return MalList(a0.values)
    elif isinstance(a0, MalList):
        if len(a0) == 0: return nil
        return a0
    elif types._string_Q(a0):
        assert isinstance(a0, MalStr)
        if len(a0) == 0: return nil
        return MalList([MalStr(unicode(c)) for c in a0.value])
    elif a0 is nil:
        return nil
    else:
        throw_str("seq: called on non-sequence")
Esempio n. 20
0
File: env.py Progetto: fengb/mal-zig
    def __init__(self, outer=None, binds=None, exprs=None):
        self.data = {}
        self.outer = outer or None

        if binds:
            assert isinstance(binds, MalList) and isinstance(exprs, MalList)
            for i in range(len(binds)):
                bind = binds[i]
                if not isinstance(bind, MalSym):
                    throw_str("env bind value is not a symbol")
                if bind.value == u"&":
                    bind = binds[i + 1]
                    if not isinstance(bind, MalSym):
                        throw_str("env bind value is not a symbol")
                    self.data[bind.value] = exprs.slice(i)
                    break
                else:
                    self.data[bind.value] = exprs[i]
Esempio n. 21
0
    def __init__(self, outer=None, binds=None, exprs=None):
        self.data = {}
        self.outer = outer or None

        if binds:
            assert isinstance(binds, MalList) and isinstance(exprs, MalList)
            for i in range(len(binds)):
                bind = binds[i]
                if not isinstance(bind, MalSym):
                    throw_str("env bind value is not a symbol")
                if bind.value == u"&":
                    bind = binds[i + 1]
                    if not isinstance(bind, MalSym):
                        throw_str("env bind value is not a symbol")
                    self.data[bind.value] = exprs.slice(i)
                    break
                else:
                    self.data[bind.value] = exprs[i]
Esempio n. 22
0
def nth(args):
    lst, idx = args[0], args[1]
    if not isinstance(lst, MalList):
        throw_str("nth called with non-list/non-vector")
    if not isinstance(idx, MalInt):
        throw_str("nth called with non-int index")
    if idx.value < len(lst): return lst[idx.value]
    else: throw_str("nth: index out of range")
Esempio n. 23
0
def read_form(reader):
    token = reader.peek()
    # reader macros/transforms
    if token[0] == ';':
        reader.next()
        return None
    elif token == '\'':
        reader.next()
        return _list(MalSym(u'quote'), read_form(reader))
    elif token == '`':
        reader.next()
        return _list(MalSym(u'quasiquote'), read_form(reader))
    elif token == '~':
        reader.next()
        return _list(MalSym(u'unquote'), read_form(reader))
    elif token == '~@':
        reader.next()
        return _list(MalSym(u'splice-unquote'), read_form(reader))
    elif token == '^':
        reader.next()
        meta = read_form(reader)
        return _list(MalSym(u'with-meta'), read_form(reader), meta)
    elif token == '@':
        reader.next()
        return _list(MalSym(u'deref'), read_form(reader))

    # list
    elif token == ')':
        types.throw_str("unexpected ')'")
    elif token == '(':
        return read_list(reader)

        # vector
    elif token == ']':
        types.throw_str("unexpected ']'")
    elif token == '[':
        return read_vector(reader)

        # hash-map
    elif token == '}':
        types.throw_str("unexpected '}'")
    elif token == '{':
        return read_hash_map(reader)

        # atom
    else:
        return read_atom(reader)
Esempio n. 24
0
def get(args):
    obj, key = args[0], args[1]
    if obj is nil:
        return nil
    elif isinstance(obj, MalHashMap):
        if not isinstance(key, MalStr):
            throw_str("get called on hash-map with non-string/non-keyword key")
        if obj and key.value in obj.dct:
            return obj.dct[key.value]
        else:
            return nil
    elif isinstance(obj, MalList):
        if not isinstance(key, MalInt):
            throw_str("get called on list/vector with non-string/non-keyword key")
        return obj.values[key.value]
    else:
        throw_str("get called on invalid type")
Esempio n. 25
0
def read_form(reader):
    token = reader.peek()
    # reader macros/transforms
    if token[0] == ';':
        reader.next()
        return None
    elif token == '\'':
        reader.next()
        return _list(MalSym(u'quote'), read_form(reader))
    elif token == '`':
        reader.next()
        return _list(MalSym(u'quasiquote'), read_form(reader))
    elif token == '~':
        reader.next()
        return _list(MalSym(u'unquote'), read_form(reader))
    elif token == '~@':
        reader.next()
        return _list(MalSym(u'splice-unquote'), read_form(reader))
    elif token == '^':
        reader.next()
        meta = read_form(reader)
        return _list(MalSym(u'with-meta'), read_form(reader), meta)
    elif token == '@':
        reader.next()
        return _list(MalSym(u'deref'), read_form(reader))

    # list
    elif token == ')': types.throw_str("unexpected ')'")
    elif token == '(': return read_list(reader)

    # vector
    elif token == ']': types.throw_str("unexpected ']'");
    elif token == '[': return read_vector(reader);

    # hash-map
    elif token == '}': types.throw_str("unexpected '}'");
    elif token == '{': return read_hash_map(reader);

    # atom
    else:              return read_atom(reader);
Esempio n. 26
0
def lte(args):
    a, b = args[0], args[1]
    if not isinstance(a, MalInt) or not isinstance(b, MalInt):
        throw_str("<= called on non-integer")
    return wrap_tf(a.value <= b.value)
Esempio n. 27
0
def slurp(args):
    a0 = args[0]
    if not isinstance(a0, MalStr):
        throw_str("slurp with non-string filename")
    return MalStr(unicode(open(str(a0.value)).read()))
Esempio n. 28
0
def read_str(args):
    a0 = args[0]
    if not isinstance(a0, MalStr):
        throw_str("read-string of non-string")
    return reader.read_str(str(a0.value))
Esempio n. 29
0
def contains_Q(args):
    hm, key = args[0], args[1]
    if not isinstance(key, MalStr):
        throw_str("contains? called on hash-map with non-string/non-keyword key")
    return wrap_tf(key.value in hm.dct)
Esempio n. 30
0
def reset_BANG(args):
    atm, val = args[0], args[1]
    if not isinstance(atm, MalAtom):
        throw_str("reset! called on non-atom")
    atm.value = val
    return atm.value
Esempio n. 31
0
def deref(args):
    atm = args[0]
    if not isinstance(atm, MalAtom):
        throw_str("deref called on non-atom")
    return atm.value
Esempio n. 32
0
def meta(args):
    obj = args[0]
    if isinstance(obj, MalMeta):
        return obj.meta
    else:
        throw_str("meta not supported on type")
Esempio n. 33
0
def cons(args):
    x, seq = args[0], args[1]
    if not isinstance(seq, MalList):
        throw_str("cons called with non-list/non-vector")
    return MalList([x] + seq.values)