Skip to content

Instantly share code, notes, and snippets.

@ympbyc
Last active December 16, 2015 09:09
Show Gist options
  • Select an option

  • Save ympbyc/5411191 to your computer and use it in GitHub Desktop.

Select an option

Save ympbyc/5411191 to your computer and use it in GitHub Desktop.
Deadly simple concatenative language.
[ :map ([a] (a -- b) -- [b])
[ over
[ [] ]
[ swap dup car rot tuck call swap rot cdr swap map swap drop swap drop swap cons ]
rot
empty? ] define,
[ 1 2 3 4 5 ] [ 2 * ] map . ]
(ns reductor)
(defn atom? [x]
(or (number? x)
(string? x)
(keyword? x)))
(declare reduct call)
(defn reduct
[[x & xs :as quot] stack words]
;;(println stack)
;;(println "")
;;(println x)
(if (empty? quot)
{:stack stack
:words words}
(cond
(atom? x) #(reduct xs (cons x stack) words)
(= x 'define) #(reduct xs (drop 3 stack) (conj words {(-> stack rest rest first) (first stack)}))
;(= x 'call) #(reduct xs (trampoline call (first stack) (rest stack) words) words) ;;consider rewriting this as a normal word
(symbol? x) #(reduct xs (trampoline call (words (keyword x)) stack words) words)
(and (coll? x) (empty? x)) #(reduct xs (cons x stack) words)
(coll? x) #(reduct xs (cons x stack) words))))
(defn call [x stack words]
(cond
(fn? x) (x stack words)
true #(-> (trampoline reduct x stack words) :stack)))
(defn t [[x y & xs] ws]
(cons (first (trampoline call y xs ws)) xs))
(defn f [[x y & xs] ws]
(cons (first (trampoline call x xs ws)) xs))
(defn main [& _]
((trampoline reduct (read) [] {:call (fn [[x & xs] ws]
(trampoline call x xs ws))
:dip (fn [[x y & xs] ws]
(cons y (trampoline call x xs ws)))
:swap (fn [[x y & xs] ws]
(concat (list y x) xs))
:rot (fn [[x y z & xs] ws]
(concat (list z x y) xs))
:dup (fn [[x & xs] ws]
(concat (list x x) xs))
:over (fn [[x y & xs] ws]
(concat [y x y] xs))
:tuck (fn [[x y & xs] ws]
(concat [x y x] xs))
:drop (fn [[x & xs] _] xs)
:. (fn [[x & _] _] x)
:car (fn [[x & xs] ws]
(cons (first x) xs))
:cdr (fn [[x & xs] ws]
(cons (rest x) xs))
:cons (fn [[x y & xs] ws]
(cons (cons x y) xs))
:t t
:f f
:empty? (fn [[x & xs] ws]
(if (empty? x) (t xs ws) (f xs ws)))
:* (fn [[x y & xs] _] (cons (* x y) xs))}) :stack))
;;example
;[ :inject5 ( x -- x y ) [ 5 swap ] define, 2 3 inject5 ]
@ympbyc
Copy link
Copy Markdown
Author

ympbyc commented Apr 18, 2013

.factorって拡張子はコードハイライトのために使ってるだけでコード自体はfactorじゃないです。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment