Implement step 8
[jackhill/mal.git] / coffee / core.coffee
CommitLineData
89524f4c 1readline = require "./node_readline"
891c3f3b
JM
2types = require "./types.coffee"
3reader = require "./reader.coffee"
4printer = require "./printer.coffee"
5[_pr_str, println] = [printer._pr_str, printer.println]
6
7# Sequence functions
8conj = (seq, args...) ->
9 switch types._obj_type(seq)
10 when 'list'
11 lst = types._clone(seq)
12 lst.unshift(x) for x in args
13 lst
14 when 'vector'
15 lst = types._clone(seq)
16 lst.push(args...)
17 types._vector(lst...)
18 else throw new Error "conj called on " + types._obj_type(seq)
19
20# Metadata functions
21with_meta = (obj,m) ->
22 new_obj = types._clone(obj)
23 new_obj.__meta__ = m
24 new_obj
25
26
27exports.ns = {
28 '=': (a,b) -> types._equal_Q(a,b),
29 'throw': (a) -> throw a,
30 'nil?': types._nil_Q,
31 'true?': types._true_Q,
32 'false?': types._false_Q,
33 'symbol': types._symbol,
34 'symbol?': types._symbol_Q,
b8ee29b2
JM
35 'keyword': types._keyword,
36 'keyword?': types._keyword_Q,
891c3f3b
JM
37
38 'pr-str': (a...) -> a.map((exp) -> _pr_str(exp,true)).join(" "),
39 'str': (a...) -> a.map((exp) -> _pr_str(exp,false)).join(""),
40 'prn': (a...) -> println(a.map((exp) -> _pr_str(exp,true))...),
41 'println': (a...) -> println(a.map((exp) -> _pr_str(exp,false))...),
42 'readline': readline.readline,
43 'read-string': reader.read_str,
44 'slurp': (a) -> require('fs').readFileSync(a, 'utf-8'),
45 '<': (a,b) -> a<b,
46 '<=': (a,b) -> a<=b,
47 '>': (a,b) -> a>b,
48 '>=': (a,b) -> a>=b,
49 '+': (a,b) -> a+b,
50 '-': (a,b) -> a-b,
51 '*': (a,b) -> a*b,
52 '/': (a,b) -> a/b,
53 'time-ms': () -> new Date().getTime(),
89524f4c 54
891c3f3b
JM
55 'list': (a...) -> a,
56 'list?': types._list_Q,
57 'vector': (a...) -> types._vector(a...),
58 'vector?': types._vector_Q,
59 'hash-map': (a...) -> types._hash_map(a...),
60 'map?': types._hash_map_Q,
61 'assoc': (a,b...) -> types._assoc_BANG(types._clone(a), b...),
62 'dissoc': (a,b...) -> types._dissoc_BANG(types._clone(a), b...),
63 'get': (a,b) -> if a != null and b of a then a[b] else null,
64 'contains?': (a,b) -> b of a,
65 'keys': (a) -> k for k of a,
66 'vals': (a) -> v for k,v of a,
67
68 'sequential?': types._sequential_Q,
69 'cons': (a,b) -> [a].concat(b),
70 'concat': (a=[],b...) -> a.concat(b...),
b8ee29b2
JM
71 'nth': (a,b) -> if a.length > b then a[b] else
72 throw new Error "nth: index out of bounds",
8d1e25ac
DM
73 'first': (a) -> if a != null and a.length > 0 then a[0] else null,
74 'rest': (a) -> if a == null then [] else a[1..],
891c3f3b 75 'empty?': (a) -> a.length == 0,
b8ee29b2 76 'count': (a) -> if a == null then 0 else a.length,
891c3f3b
JM
77 'apply': (a,b...) -> a(b[0..-2].concat(b[b.length-1])...),
78 'map': (a,b) -> b.map((x) -> a(x)),
79 'conj': conj,
80
81 'with-meta': with_meta,
82 'meta': (a) -> a.__meta__ or null,
83 'atom': types._atom,
84 'atom?': types._atom_Q,
85 'deref': (a) -> a.val,
86 'reset!': (a,b) -> a.val = b,
87 'swap!': (a,b,c...) -> a.val = b([a.val].concat(c)...), }
88
89# vim: ts=2:sw=2