mirror of
https://github.com/kanaka/mal.git
synced 2024-09-21 10:37:58 +03:00
127 lines
3.2 KiB
PostScript
127 lines
3.2 KiB
PostScript
|
(in core.ps\n) print
|
||
|
|
||
|
% requires types.ps
|
||
|
|
||
|
% Errors/Exceptions
|
||
|
|
||
|
% data -> throw ->
|
||
|
% Takes an arbitrary data and puts it in $error:/errorinfo. Then calls
|
||
|
% stop to transfer control to end of nearest stopped context.
|
||
|
/throw {
|
||
|
$error exch /errorinfo exch put
|
||
|
$error /command /throw put
|
||
|
stop
|
||
|
} def
|
||
|
|
||
|
|
||
|
% sequence functions
|
||
|
|
||
|
% [obj list] -> cons -> new_list
|
||
|
/cons {
|
||
|
/args exch def
|
||
|
/elem args 0 get def
|
||
|
/lst args 1 get def
|
||
|
lst length 1 add array
|
||
|
dup 0 elem put % first element
|
||
|
dup 1 lst putinterval % rest of the elements
|
||
|
} def
|
||
|
|
||
|
% [listA listB] -> concat -> [listA... listB...]
|
||
|
/concat { % replaces matric concat
|
||
|
dup length 0 eq { %if just concat
|
||
|
0 _list
|
||
|
}{ dup length 1 eq { %elseif concat of single item
|
||
|
0 get % noop
|
||
|
}{ % else
|
||
|
[] exch
|
||
|
{
|
||
|
concatenate
|
||
|
} forall
|
||
|
} ifelse } ifelse
|
||
|
} def
|
||
|
|
||
|
% [obj ...] -> first -> obj
|
||
|
/first {
|
||
|
0 get _first
|
||
|
} def
|
||
|
|
||
|
% [obj objs...] -> first -> [objs..]
|
||
|
/rest {
|
||
|
0 get _rest
|
||
|
} def
|
||
|
|
||
|
% [function args... arg_list] -> apply -> result
|
||
|
/apply { 1 dict begin
|
||
|
/args exch def
|
||
|
args 0 get callable % make sure function is callable
|
||
|
args 1 args length 2 sub getinterval
|
||
|
args args length 1 sub get
|
||
|
concatenate args 0 get % stack: args function
|
||
|
exec
|
||
|
end } def
|
||
|
|
||
|
% [function list] -> _map -> new_list
|
||
|
/map { 1 dict begin
|
||
|
dup 0 get exch 1 get % stack: function list
|
||
|
/args exch def
|
||
|
callable % make sure function is callable
|
||
|
%/new_list args length array def
|
||
|
args {
|
||
|
1 array astore
|
||
|
exch dup 3 1 roll % stack: fn arg fn
|
||
|
exec exch % stack: result fn
|
||
|
} forall
|
||
|
pop % remove the function
|
||
|
args length array astore
|
||
|
end } def
|
||
|
|
||
|
/conj { 5 dict begin
|
||
|
/args exch def
|
||
|
/src_list args 0 get def
|
||
|
/new_len src_list length args length 1 sub add def
|
||
|
/new_list new_len array def
|
||
|
new_list new_len src_list length sub src_list putinterval
|
||
|
args length 1 sub -1 1 {
|
||
|
/idx exch def
|
||
|
new_list args length idx sub 1 sub args idx get put
|
||
|
} for
|
||
|
new_list
|
||
|
end } def
|
||
|
|
||
|
|
||
|
% core_ns is namespace of core functions
|
||
|
|
||
|
/core_ns <<
|
||
|
(pr-str) { ( ) true _pr_str_args }
|
||
|
(str) { () false _pr_str_args }
|
||
|
(prn) { ( ) true _pr_str_args print (\n) print null }
|
||
|
(println) { () false _pr_str_args print (\n) print null }
|
||
|
(=) { dup 0 get exch 1 get _equal? }
|
||
|
(symbol?) { 0 get _symbol? }
|
||
|
(nil?) { 0 get _nil? }
|
||
|
(true?) { 0 get _true? }
|
||
|
(false?) { 0 get _false? }
|
||
|
(<) { dup 0 get exch 1 get lt }
|
||
|
(<=) { dup 0 get exch 1 get le }
|
||
|
(>) { dup 0 get exch 1 get gt }
|
||
|
(>=) { dup 0 get exch 1 get ge }
|
||
|
(+) { dup 0 get exch 1 get add }
|
||
|
(-) { dup 0 get exch 1 get sub }
|
||
|
(*) { dup 0 get exch 1 get mul }
|
||
|
(/) { dup 0 get exch 1 get idiv }
|
||
|
(throw) { 0 get throw }
|
||
|
(list) { dup pop } % noop
|
||
|
(list?) { 0 get _list? }
|
||
|
(cons) { cons }
|
||
|
(concat) { concat }
|
||
|
(sequential?) { 0 get _sequential? }
|
||
|
(empty?) { 0 get length 0 eq }
|
||
|
(count) { 0 get length }
|
||
|
(nth) { dup 0 get exch 1 get _nth }
|
||
|
(first) { first }
|
||
|
(rest) { rest }
|
||
|
(apply) { apply }
|
||
|
(map) { map }
|
||
|
(conj) { conj }
|
||
|
>> def
|