diff options
| author | Joel Martin <github@martintribe.org> | 2014-04-01 21:50:24 -0500 |
|---|---|---|
| committer | Joel Martin <github@martintribe.org> | 2014-04-01 21:50:24 -0500 |
| commit | 950e3c765e30648de34cfc4f65fffdce06f0727f (patch) | |
| tree | 3e66b70a71a5cfa01671830d80d7ea7926509b2d /ps/types.ps | |
| parent | 704194e12c5080f5c6842416a78fe7efa09da068 (diff) | |
| download | mal-950e3c765e30648de34cfc4f65fffdce06f0727f.tar.gz mal-950e3c765e30648de34cfc4f65fffdce06f0727f.zip | |
PS: add stepA_more.
Sync other steps. In particular, self reference in function definition
and putting readline into _readline function.
Diffstat (limited to 'ps/types.ps')
| -rw-r--r-- | ps/types.ps | 90 |
1 files changed, 84 insertions, 6 deletions
diff --git a/ps/types.ps b/ps/types.ps index 1eb2cf5..30019b9 100644 --- a/ps/types.ps +++ b/ps/types.ps @@ -7,7 +7,7 @@ /concatenate { %def dup type 2 index type 2 copy ne { %if pop pop - errordict begin (concatentate) typecheck end + errordict begin (concatenate) typecheck end }{ %else /stringtype ne exch /arraytype ne and { errordict begin (concatenate) typecheck end @@ -120,6 +120,11 @@ end } def } ifelse end } def +/_nil? { null eq } def +/_true? { true eq } def +/_false? { false eq } def + + % % Symbols % @@ -147,6 +152,10 @@ end } def env_new % stack: ast new_env } def +% 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 + % % Errors/Exceptions % @@ -199,8 +208,6 @@ end } def /_list? { dup xcheck not exch type /arraytype eq and } def -/_first { 0 get } def -/_rest { dup length 1 sub 1 exch getinterval } def /_nth { get } def /_cons { @@ -211,10 +218,72 @@ end } def dup 1 lst putinterval % rest of the elements } def -/_concat { - concatenate +/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 + +% +% Sequence operations +% +/_first { + dup length 0 gt { 0 get }{ pop null } ifelse +} def +/_rest { + dup length 0 gt { + dup length 1 sub 1 exch getinterval + }{ + pop 0 array + } ifelse } 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 + /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 + +/_sequential? { _list? } 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 + % % Env implementation @@ -286,6 +355,10 @@ end } def (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 } @@ -294,13 +367,18 @@ end } def (-) { 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) { dup 0 get exch 1 get _cons } - (concat) { dup 0 get exch 1 get _concat } + (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) { 0 get _first } (rest) { 0 get _rest } + (apply) { apply } + (map) { dup 0 get exch 1 get _map } + (conj) { conj } >> def |
