Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Extended microstack.

  • Loading branch information...
commit 9035699c685b8764b50c09f070ce3ae12b766e9b 1 parent c95dfaf
@VincentToups authored
Showing with 105 additions and 42 deletions.
  1. +0 −2  lisp-parser.el
  2. +74 −35 microstack.el
  3. +31 −5 microstack.md
View
2  lisp-parser.el
@@ -52,8 +52,6 @@
(=let* [_ (=string "\\\"")]
(if _ ?\" nil)))
-?\"
-
(setq space ?\s)
(defun =spaces ()
View
109 microstack.el
@@ -12,13 +12,29 @@
(if _
(intern (concat (list _))) nil)))
+(defunc =escaped-close-bracket ()
+ "Parse an escaped close bracket."
+ "["
+ (=let* [_ (=string "\\]")]
+ (if _ ?\" nil)))
+
+(defunc =bracketed-string ()
+ (=let* [_ (=char ?\[)
+ contents (zero-or-more (=or
+ (=escaped-close-bracket)
+ (=satisfies
+ (lex-lambda (c) (!= c ?\])))))
+ _ (=char ?\])]
+ (parse-and-translate-microstack (coerce (flatten contents) 'string))))
+
(defun microstack-parser ()
"Parser for the microstack language."
(zero-or-more (=or
(=microstack-symbol)
(=number)
- (=lisp-string))))
+ (=lisp-string)
+ (=bracketed-string))))
(defun parse-microstack (code)
"Parse the microstack language and return the results as a sequence of symbols, numbers, strings. Remove no-ops."
@@ -73,43 +89,61 @@
do
(|||- {qtn} call))))
+(defstackword forward
+ (forward-char))
+(defstackword backward
+ (backward-char))
+
+(defstackword format
+ (let ((fmtstr (pop *stack*))
+ (rest (pop *stack*)))
+ (push (apply #'format (cons fmtstr rest)) *stack*)))
+
(setq micro-stack-map
(alist>>
- 'b '0>backward-char
- 'B '1>backward-char
- 'f '0>forward-char
- 'F '1>forward-char
- 'd 'delete-forward0
- 'D 'delete-forward
- 'k 'delete-backward0
- 'K 'delete-backward
- 'q 'microstack->quotation
- 'Q 'string->quotation
- '! 'call
- '? 'if
- '+ '+
- '- '-
- 't 't
- '_ 'nil
- 'm '0>push-mark
+ 'b 'backward ; move the point backward once
+ 'B '1>backward-char ; move the point backward n times, pop n from the stack
+ 'f 'forward ; move the point forward once
+ 'F '1>forward-char ; move the point forward n times, pop n from the stack
+ 'd 'delete-forward0 ; delete forward once
+ 'D 'delete-forward ; delete forward n times, pop n from the stack
+ 'k 'delete-backward0 ; delete backward once
+ 'K 'delete-backward ; delete backward n times, remove n from the stack
+ 'q 'microstack->quotation ; convert a STRING to a microstack compiled quotation, "..."q is eq to [...]
+ 'Q 'string->quotation ;push the stack word represented by string onto the stack to be called later
+ '! 'call ; call a quotation/stack word
+ '? 'if ; if
+ '+ '+ ; plus
+ '- '- ; -
+ 't 't ; push t
+ '_ 'nil ; push nil
+ 'm '0>push-mark ; mark the current point as the mark
'M '0>mark ; put the mark position on the stack
- 'g '1>goto-char
- 'x 'kill-current-region
- '* '*
- '/ '/
- '= '2>equal
- 'N 'do-n-times
- 'L 'loop
- 's '1>search-forward
- 'S '1>search-forward-regexp
- 'c 'concat
- (intern ",") 'print-stack
- (intern ":") 'dup
- '@ 'char-at-point->string
- (intern ".") 'print
- 'U 'loop-until
- 'W 'loop-while
- 'i 'insert))
+ 'g '1>goto-char ; jump to a character number popped from the stack
+ 'x 'kill-current-region ; kill the current region between the point and mark
+ '* '* ; times
+ '/ '/ ; divide
+ '= '2>equal ; equals
+ 'N 'do-n-times ; do a quotation n times before stopping
+ 'L 'loop ; the loop word in all its general glory - execute a quotation until the top of the stack is true
+ '{ '{{ ; start a list
+ '} '}} ; end a list
+ 's '1>search-forward ; search forward for the string on the stack, which is popped
+ 'S '1>search-forward-regexp ; search forward for the regex on the stack, which is popped
+ 'c 'concat ; concat two strings
+ (intern ",") 'print-stack ; print the stack
+ (intern ":") 'dup ; dup
+ (intern "$") 'swap ; swap the top two stack elements
+ (intern "#") 'length ; pop object off the stack and push its length
+ (intern "@") 'char-at-point->string ;push the current character onto the stack
+ (intern ".") 'print ; print the top of the stack, pop it
+ (intern "%") 'format ; lst format-string format; calls format with the string format-string and lst as rest args
+ 'U 'loop-until ; qt pred loop-until ; loop qt until pred is true
+ 'W 'loop-while ; qt pred loop-while ; loop qt while pred is true
+ 'i 'insert ; insert the top of the stack as text into the buffer
+))
+
+
(defun translate-microstack (code)
"Translate the single character symbols to their stack words. Process special microstack behavior words."
@@ -118,8 +152,13 @@
((symbolp el)
(let ((trans (alist micro-stack-map el)))
(if trans (list trans) (error "Unknown microstack word."))))
+ ((listp el)
+ (list 'lisp-val: `(quote ,el)))
(t (list el)))))
+(defun parse-and-translate-microstack (code)
+ (translate-microstack (parse-microstack code)))
+
(defun do-microstack-parsed-translated (code)
"Evaluate the parsed and translated CODE for a microstack statement. Should be regular stack code at this point."
(eval `(|||p ,@code)))
View
36 microstack.md
@@ -31,7 +31,7 @@ position in the buffer, and then inserted the text "test".
If you enter instead
- "k"q10N
+ [k]10N
You'll find emacs has deleted the last ten characters.
@@ -46,10 +46,36 @@ can be rewritten with extra spaces, if you want to.
What the hell is going on here?
-------------------------------
-Microstack takes a specially formatted string, parses it into a series
-of single-character "operands," numbers or strings and then passes
-that sequence through a translator which transforms symbols into
-stack-language words using a dictionary.
+Lets take a more complex example than the ones above and read it out
+piece by piece, then discuss its stack language representation.
+
+ [d][@"}"=]U
+
+This piece of code reads "delete forward until you reach a }". How do
+I get that from the above? `[d]` is a quotation, because it starts
+with `[` and ends with `]`. `d` means "delete forward". So `[d]`
+pushes a quotation which, when called, deletes one character forward.
+
+Immediately after this quotation is another, `[@"}"=]`, which pushes
+the character under the cursor onto the stack (`@`), pushes "}", and
+then pushes the result of testing whether they are equal (`=`).
+Remember, this is just a quotation, so its just pushed onto the stack.
+Neither quote is evaluated yet.
+
+The next operand is `U`, which stands for `loop-until`, a stack word
+which executes the lower quotation until the upper quotation pushes a
+true onto the stack. `Loop-unti` consumes the sentinal value on each
+loop. Putting all this together, we recover "delete forward until a
+}".
+
+In general, microstack takes a specially formatted string, parses it
+into a series of single-character "operands," numbers or strings and
+then passes that sequence through a translator which transforms
+symbols into stack-language words using a dictionary. Operands are
+single characters, strings are like Lisp strings, numbers like lisp
+numbers, and the only special syntax is `[]` for quotation.
+Everything inside a `[]` is compiled into a stack-quotation using the
+microstack compiler.
The idea is to provide the most useful/common stack language words for
text manipulation as single character operands, for brevity, while
Please sign in to comment.
Something went wrong with that request. Please try again.