1
1
mirror of https://github.com/kanaka/mal.git synced 2024-09-21 10:37:58 +03:00
mal/ps/types.ps

161 lines
3.3 KiB
PostScript
Raw Normal View History

2014-03-30 00:56:20 +04:00
(in types.ps\n) print
% General functions
2014-03-30 00:56:20 +04:00
% concatenate: concatenate two strings or two arrays
% From Thinking in PostScript 1990 Reid
% (string1) (string2) concatenate string3
% array1 array2 concatenate array3
/concatenate { %def
dup type 2 index type 2 copy ne { %if
pop pop
errordict begin (concatenate) typecheck end
2014-03-30 00:56:20 +04:00
}{ %else
/stringtype ne exch /arraytype ne and {
errordict begin (concatenate) typecheck end
} if
} ifelse
dup length 2 index length add 1 index type
/arraytype eq { array }{ string } ifelse
% stack: arg1 arg2 new
dup 0 4 index putinterval
% stack: arg1 arg2 new
dup 4 -1 roll length 4 -1 roll putinterval
% stack: new
} bind def
2014-03-30 02:01:24 +04:00
% reverse: array1 -> reverse -> array2
/reverse {
[ exch
aload % push array onto stack
length -1 0 { 1 roll } for % reverse
]
} bind def
2014-03-30 02:01:24 +04:00
2014-03-30 03:20:07 +04:00
% objA objB -> _equal? -> bool
/_equal? { 6 dict begin
/b exch def
/a exch def
/ota a type def
/otb b type def
a type b type eq
a _list? b _list? and
or not { %if type mismatch and not sequential
false
}{
a _list? { %if list
/ret true def
a length b length eq not { %if length mismatch
/ret false def
}{ %else (length is the same)
0 1 a length 1 sub {
/idx exch def
a idx get b idx get _equal? not { %if not items _equal?
/ret false def
exit
} if
} for
} ifelse
ret
}{ %else not a list
a b eq
} ifelse
} ifelse
end } def
/_sequential? { _list? } def
/_first {
dup length 0 gt { 0 get }{ pop null } ifelse
2014-03-31 07:39:44 +04:00
} def
/_rest {
dup length 0 gt {
dup length 1 sub 1 exch getinterval
}{
pop 0 array
} ifelse
} def
2014-03-31 07:39:44 +04:00
% Errors/Exceptions
2014-03-30 00:56:20 +04:00
/errorinfo? {
$error /errorinfo known { % if set
$error /errorinfo get null ne {
true
}{
false
} ifelse
}{
false
} ifelse
2014-03-30 00:56:20 +04:00
} def
2014-03-30 02:26:07 +04:00
/get_error_data {
errorinfo? { %if
$error /errorinfo get
}{
$error /errorname get 255 string cvs
(: )
$error /command get 99 string cvs
( at )
$error /position get 10 99 string cvrs
concatenate
concatenate
concatenate
concatenate
} ifelse
} def
2014-03-30 02:26:07 +04:00
% Scalars
/_nil? { null eq } def
/_true? { true eq } def
/_false? { false eq } def
2014-03-30 02:26:07 +04:00
2014-03-31 07:39:44 +04:00
% Symbols
/_symbol? {
type /nametype eq
2014-03-31 07:39:44 +04:00
} def
% Functions
/_mal_function? {
dup type /dicttype eq {
/type get /_maltype_function eq
}{
pop false
} ifelse
} def
% args mal_function -> fload -> ast new_env
% fload: sets up arguments on the stack for an EVAL call
/fload {
dup /ast get 3 1 roll % stack: ast args mal_function
dup /env get 3 1 roll % stack: ast env args mal_function
/params get exch % stack: ast env params args
env_new % stack: ast new_env
} def
2014-03-30 02:26:07 +04:00
% function_or_block -> callable -> block
% if this is a user defined mal function, get its executable block
/callable { dup _mal_function? { /data get } if } def
2014-03-30 02:26:07 +04:00
% Lists
2014-03-30 02:26:07 +04:00
/_list {
array astore
} def
/_list? {
dup xcheck not exch type /arraytype eq and
} def
/_nth { get } def
2014-03-30 03:20:07 +04:00