Permalink
Browse files

Added swap, dip, i, nullary, step, fold, concat. Also added aspiratio…

…ns to the README
  • Loading branch information...
stevej committed Oct 5, 2012
1 parent c15f32e commit 4d245e362fb5370b619d3ea35107032e72eda766
Showing with 108 additions and 13 deletions.
  1. +29 −2 README.md
  2. +79 −11 src/Stackist/Interpreter1.hs
View
@@ -3,7 +3,34 @@
[![Build Status](https://secure.travis-ci.org/stevej/stackist.png?branch=master)](http://travis-ci.org/stevej/stackist)
`stackist` is a series of experiments in building a stack-based
-programming language.
+programming language, starting with Manfred von Thun's Joy language.
-What we have today:
+What I have today:
* A basic interpreter for an arithmetic language.
+* Literals
+* Operators
+* A basic stdandard library
+* Quotations
+* Most of the base combinators
+
+
+What I'm working on next:
+* Aggregates
+* All combinators (primrec, linrec, binrec, fold, ifte)
+* Critical: verify that my stack semantics agree with von Thun's.
+* More stdlib (working down this list: http://www.latrobe.edu.au/phimvt/joy/html-manual.html)
+* Named functions
+* I/O
+* stack operators (newstack, clear, stack, cons, swons, uncons, unswons)
+* better interpretor error handling
+
+Future directions:
+* Documenting a type system for Joy
+* Can we encode Joy with a fragment of System F? (rank-2?)
+* Type reconstructor applicable to all original Joy programs
+* Retargetable compiler
+* Compile to C
+* Compile to LLVM IR
+* Compile to Native code
+* Applying Linear types to Joy
+* Linear type reconstruction
@@ -8,16 +8,22 @@ import Text.Show.Functions
data Expr = Numeric Integer
| Literal String
- | Quote Expr
+ | JString String -- is "quoted"
+ | Quote [Expr]
deriving (Show, Eq)
-
-- Ladies and Gentlemen, the standard library
-- All functions are typed: [Expr] -> [Expr]
+-- | i : [P] -> ... Executes P. So, [P] i == P.
+--
+-- >> redex [] [JString "a", JString "b", Quote [Literal "concat"], Literal "i"]
+-- [JString "ab"]
+_i (Quote q : xs) = redex xs q
+
-- | Adds two numbers on bottom of the stack
--
--- >>> redex [] [Numeric 1, Numeric 2, Literal "+"]
+-- >> redex [] [Numeric 1, Numeric 2, Literal "+"]
-- [Numeric 3]
_add (Numeric m : Numeric n : xs) = Numeric (m + n) : xs
@@ -27,7 +33,7 @@ _add (Numeric m : Numeric n : xs) = Numeric (m + n) : xs
-- [Numeric 2]
_subtract (Numeric m : Numeric n : xs) = Numeric (n - m) : xs
--- | Multiples the bottom two numbers on the stack together
+-- | Multiplies the bottom two numbers on the stack together
--
-- >>> redex [] [Numeric 2, Numeric 3, Literal "*"]
-- [Numeric 6]
@@ -48,36 +54,98 @@ _dup (m : xs) = m : m : xs
-- | Swaps the two top items on the stack
--
-- >>> redex [] [Numeric 3, Numeric 2, Literal "swap"]
--- [Numeric 2,Numeric 3]
-_swap (m : n : xs) = m : n : xs -- note they're already in reverse order
+-- [Numeric 3,Numeric 2]
+_swap (m : n : xs) = n : m : xs
+
+-- | dip : X [P] -> ... X
+-- Saves X, executes P, pushes X back.
+--
+-- >> redex [] [Numeric 1, Quote [Numeric 2, Numeric 2, Literal "+"], Literal "dip"]
+-- [Numeric 4, Numeric 1]
+_dip (m : Quote q : xs) = r ++ (m : xs)
+ where r = _i (Quote q : xs)
+
+-- | [P] -> R Executes P, which leaves R on top of the stack. No matter
+-- how many parameters this consumes, none are removed from the stack.
+--
+-- >>> redex [] [Quote [Numeric 1, Numeric 2, Literal "+"], Literal "nullary"]
+-- [Numeric 3]
+_nullary (Quote q : xs) = (redex [] q) ++ xs
+-- how to keep the rest of the stack from being affected?
+
+-- | S T -> U Sequence U is the concatenation of sequences S and T.
+--
+-- >> redex [] [JString "a", JString "b", Literal "concat"]
+-- [JString "ab"]
+_concat (JString s : JString t : xs) = JString (s ++ t) : xs
+
+-- | fold : A V0 [P] -> V Starting with value V0, sequentially pushes
+-- members of aggregate A and combines with binary operator P to produce value V.
+-- (SJ: I assumed this would be a foldRight but is left)
+-- List("b", "c", "d").foldLeft("a")((a,b) => a + b)
+-- res1: java.lang.String = abcd
+--
+-- >> redex [] [Quote [JString "b", JString "c", JString "d"], JString "a", Quote [Literal "concat"], Literal "fold"]
+-- [JString "abcd"]
+_fold = _swapd . _step
+-- | swapd : X Y Z -> Y X Z
+-- As if defined by: swapd == [swap] dip
+--
+-- >> redex [] [Literal "x", Literal "y", Literal "z", Literal "swapd"]
+-- [Literal "z", Literal "x", Literal "y"]
+_swapd (z : y : x : xs) = z : x : y : xs
+
+
+-- | step : A [P] -> ...
+-- Sequentially putting members of aggregate A onto stack, executes
+-- P for each member of A.
+--
+-- >> redex [] [Quote [Numeric 1, Numeric 2], Quote [Numeric 2, Literal "*"], Literal "step"]
+-- [Numeric 4, Numeric 1]
+_step (Quote qs : Quote f : xs) = (concat (map f' qs)) ++ xs
+ where f' q = redex [q] f
+
preludeMap :: Map.Map String ([Expr] -> [Expr])
preludeMap = Map.fromList
[("+", _add),
("-", _subtract),
("*", _multiply),
("/", _divide),
("dup", _dup),
- ("swap", _swap)
+ ("swap", _swap),
+ ("nullary", _nullary),
+ ("concat", _concat),
+ ("fold", _fold),
+ ("dip", _dip),
+ ("i", _i),
+ ("swapd", _swapd),
+ ("step", _step)
]
-- If the user is looking for a function we don't have, throw an error.
preludeLookup s = Map.findWithDefault (\_ -> error ("function not found in library: " ++ s)) s preludeMap
--- the first [Expr] is the work-in-progress stack, which will be in reverse order
--- from the program list to faciliate pattern matching on the head.
+-- the first [Expr] is the data stack, which will be in reverse order
+-- from the program list to faciliate pattern matching on the head. The second [Expr] is
+-- what we haven't processed yet.
redex :: [Expr] -> [Expr] -> [Expr]
--- | we're out of commands to run, we've finished reducing the stack.
+-- | we're out of commands to run, we've finished reducing the program stack.
--
-- >>> redex [] []
-- []
redex stack [] = stack
+-- | push a quotation onto the stack
+--
+-- >>> redex [] [Quote [Literal 1]]
+-- [Quote [Literal 1]]
+redex stack (q @ (Quote _) : xs) = redex (q : stack) xs
-- | push a number onto stack.
--
-- >>> redex [] [Numeric 1]
-- [Numeric 1]
-redex stack (n @ (Numeric m) : xs) = redex (n : stack) xs
+redex stack (n @ (Numeric _) : xs) = redex (n : stack) xs
-- | Lookup the function named s, and run it against the stack.
redex stack (Literal f : xs) = redex result xs
where result = preludeLookup f stack

0 comments on commit 4d245e3

Please sign in to comment.