New page wikitext, after the edit (new_wikitext) | '{{infobox proglang
|name=Reverse Polish Scheme
|paradigms=Imperative, Stack-Based, Functional
|author=[[User:McGoron|Peter McGoron]]
|year=2025
|class=Turing Complete
|majorimpl=[https://github.com/mcgoron-peter/reverse-polish-scheme R4RS]
|influence=Scheme, FORTH
}}
'''Reverse Polish Scheme''' (RPS) is a homoiconic, stack-based programming language with reified continuations. Its syntax is a subset of Scheme.
RPS can only use <code>call/cc</code> to manipulate the stack and instruction pointer. Stack operations, returns from calls, closures, delimited continuations, and all sorts of other fun things can be created using RPS's <code>call/cc</code>.
== Core ==
RPS syntax is a subset of Scheme.
Line comments start with <code>;</code>. Nested block comments start with <code>#|</code> and end with <code>|#</code>. Writing a number, string, <code>#t</code>, or <code>#f</code> will push that literal value onto the stack. Writing an identifier will execute that identifier.
A literal vector is introduced with <code>#(</code> and ends with <code>)</code>. A literal list (a linked list where each list cell is a vector of two elements) starts with ( and ends with ). The empty list (nil) is represented by (). A literal identifier is introduced with <code>'</code>. (Note that lists and vectors are not quoted.)
A procedure is a linked list whose first element can be used for data storage, and whose tail is a linked list of instructions to execute. By convention, procedures that do not have any data to save in their first element have their first element be <code>#f</code>.
If the interpreter hits the end of a procedure, it will halt.
The following are the built in instructions. Instructions will execute and continue at the next instruction (exceptions are <code>call/cc</code> and <code>jump</code>). They will consume all specified arguments to them.
{| class="wikitable"
!Command
!Description
|-
| style="text-align:center"| <code>proc to from call/cc</code>
|The fundamental stack manipulator. Jump to <code>proc</code> with the continuation <code>cc</code> pushed to the stack. When <code>m cc jump</code> is called, control returns to the instruction after <code>call/cc</code>, except that the stack is the <code>m</code> values on the stack before the jump appended to the values on the stack from <code>from</code> inclusive to <code>to</code> exclusive at the site of call/cc's invocation. If <code>from</code> is <code>#f</code>, then it will capture the entire stack starting from <code>to</code> exclusive.
|-
| style="text-align:center"| <code>bool on-false on-true if</code>
|If <code>bool</code> is <code>#f</code>, jump to the procedure <code>on-false</code>. Otherwise jump to the procedure <code>on-true</code>.
|-
| style="text-align:center"| <code>proc jump</code>
|The next executed instruction will be the first instruction of <code>proc</code>. Note that is no return stack.
|-
| style="text-align:center"| <code>n vector</code>
|Allocate a vector of <code>n</code> cells and push it to the stack.
|-
| style="text-align:center"| <code>vec vector-length</code>
|Push the length in cells of <code>vec</code>. Returns <code>#f</code> if <code>vec</code> is not a vector.
|-
| style="text-align:center"| <code>vec n ref</code>
|Push the <code>n</code>th cell of <code>vec</code> to the stack.
|-
| style="text-align:center"| <code>value n vec set!</code>
|Set the <code>n</code>th cell of <code>vec</code> to <code>value</code>.
|-
| style="text-align:center"| <code>x y eqv?</code>
|Pushes a boolean indicating if <code>x</code> and <code>y</code> are equivalent objects (i.e. the same vector or equal numbers).
|-
| style="text-align:center"| <code>x symbol?</code>
|Pushes a boolean indicating if <code>x</code> is a symbol.
|-
| style="text-align:center" | <code>x integer?</code>
|Pushes a boolean indicating if <code>x</code> is an exact integer.
|-
| style="text-align:center" | <code>x real?</code>
|Pushes a boolean indicating if <code>x</code> is a real.
|-
| style="text-align:center" | <code>x y +</code>
| Pushes <code>x + y</code>.
|-
| style="text-align:center" | <code>x y *</code>
| Pushes <code>x * y</code>.
|}
== Examples ==
The stack is notated as if it was a LISP list. The first element of the list is the top of the stack.
The following code will duplicate the top of the stack.
1 (#f jump) #f 1 call/cc
Explanation:
* 1, a procedure, <code>#f</code>, 1 are pushed to the stack. The stack looks like <code>(1 #f <proc> 1 x values ...)</code>.
* <code>call/cc</code> is invoked. It will jump to <code><proc></code> with the stack <code>(<cc> 1 x values ...)</code>.
* <code><cc></code> is jumped into with the argument <code>1</code>. It will return to the position after the invocation of <code>call/cc</code>, pushing <code>x</code> onto a stack that was the stack at the invocation of <code>call/cc</code>, sans one element (the first 1 pushed). Hence the stack is <code>(x x values ...)</code>.
This code is normally inlined and used as a macro. A Lisp interpreter can be used as a value-level macro processor for RPS. Since there is no lexical scope, there is no need for hygienic macros. Quasiquote works well to splice in code.
[[Category:Languages]]
[[Category:Functional paradigm]]
[[Category:2025]]
[[Category:Stack-based]]
[[Category:Turing complete]]
[[Category:No IO]]
[[Category:Implemented]]' |
Unified diff of changes made by edit (edit_diff) | '@@ -1,0 +1,94 @@
+{{infobox proglang
+|name=Reverse Polish Scheme
+|paradigms=Imperative, Stack-Based, Functional
+|author=[[User:McGoron|Peter McGoron]]
+|year=2025
+|class=Turing Complete
+|majorimpl=[https://github.com/mcgoron-peter/reverse-polish-scheme R4RS]
+|influence=Scheme, FORTH
+}}
+
+'''Reverse Polish Scheme''' (RPS) is a homoiconic, stack-based programming language with reified continuations. Its syntax is a subset of Scheme.
+RPS can only use <code>call/cc</code> to manipulate the stack and instruction pointer. Stack operations, returns from calls, closures, delimited continuations, and all sorts of other fun things can be created using RPS's <code>call/cc</code>.
+
+== Core ==
+
+RPS syntax is a subset of Scheme.
+
+Line comments start with <code>;</code>. Nested block comments start with <code>#|</code> and end with <code>|#</code>. Writing a number, string, <code>#t</code>, or <code>#f</code> will push that literal value onto the stack. Writing an identifier will execute that identifier.
+
+A literal vector is introduced with <code>#(</code> and ends with <code>)</code>. A literal list (a linked list where each list cell is a vector of two elements) starts with ( and ends with ). The empty list (nil) is represented by (). A literal identifier is introduced with <code>'</code>. (Note that lists and vectors are not quoted.)
+
+A procedure is a linked list whose first element can be used for data storage, and whose tail is a linked list of instructions to execute. By convention, procedures that do not have any data to save in their first element have their first element be <code>#f</code>.
+
+If the interpreter hits the end of a procedure, it will halt.
+
+The following are the built in instructions. Instructions will execute and continue at the next instruction (exceptions are <code>call/cc</code> and <code>jump</code>). They will consume all specified arguments to them.
+
+{| class="wikitable"
+!Command
+!Description
+|-
+| style="text-align:center"| <code>proc to from call/cc</code>
+|The fundamental stack manipulator. Jump to <code>proc</code> with the continuation <code>cc</code> pushed to the stack. When <code>m cc jump</code> is called, control returns to the instruction after <code>call/cc</code>, except that the stack is the <code>m</code> values on the stack before the jump appended to the values on the stack from <code>from</code> inclusive to <code>to</code> exclusive at the site of call/cc's invocation. If <code>from</code> is <code>#f</code>, then it will capture the entire stack starting from <code>to</code> exclusive.
+|-
+| style="text-align:center"| <code>bool on-false on-true if</code>
+|If <code>bool</code> is <code>#f</code>, jump to the procedure <code>on-false</code>. Otherwise jump to the procedure <code>on-true</code>.
+|-
+| style="text-align:center"| <code>proc jump</code>
+|The next executed instruction will be the first instruction of <code>proc</code>. Note that is no return stack.
+|-
+| style="text-align:center"| <code>n vector</code>
+|Allocate a vector of <code>n</code> cells and push it to the stack.
+|-
+| style="text-align:center"| <code>vec vector-length</code>
+|Push the length in cells of <code>vec</code>. Returns <code>#f</code> if <code>vec</code> is not a vector.
+|-
+| style="text-align:center"| <code>vec n ref</code>
+|Push the <code>n</code>th cell of <code>vec</code> to the stack.
+|-
+| style="text-align:center"| <code>value n vec set!</code>
+|Set the <code>n</code>th cell of <code>vec</code> to <code>value</code>.
+|-
+| style="text-align:center"| <code>x y eqv?</code>
+|Pushes a boolean indicating if <code>x</code> and <code>y</code> are equivalent objects (i.e. the same vector or equal numbers).
+|-
+| style="text-align:center"| <code>x symbol?</code>
+|Pushes a boolean indicating if <code>x</code> is a symbol.
+|-
+| style="text-align:center" | <code>x integer?</code>
+|Pushes a boolean indicating if <code>x</code> is an exact integer.
+|-
+| style="text-align:center" | <code>x real?</code>
+|Pushes a boolean indicating if <code>x</code> is a real.
+|-
+| style="text-align:center" | <code>x y +</code>
+| Pushes <code>x + y</code>.
+|-
+| style="text-align:center" | <code>x y *</code>
+| Pushes <code>x * y</code>.
+|}
+
+== Examples ==
+
+The stack is notated as if it was a LISP list. The first element of the list is the top of the stack.
+
+The following code will duplicate the top of the stack.
+
+ 1 (#f jump) #f 1 call/cc
+
+Explanation:
+
+* 1, a procedure, <code>#f</code>, 1 are pushed to the stack. The stack looks like <code>(1 #f <proc> 1 x values ...)</code>.
+* <code>call/cc</code> is invoked. It will jump to <code><proc></code> with the stack <code>(<cc> 1 x values ...)</code>.
+* <code><cc></code> is jumped into with the argument <code>1</code>. It will return to the position after the invocation of <code>call/cc</code>, pushing <code>x</code> onto a stack that was the stack at the invocation of <code>call/cc</code>, sans one element (the first 1 pushed). Hence the stack is <code>(x x values ...)</code>.
+
+This code is normally inlined and used as a macro. A Lisp interpreter can be used as a value-level macro processor for RPS. Since there is no lexical scope, there is no need for hygienic macros. Quasiquote works well to splice in code.
+
+[[Category:Languages]]
+[[Category:Functional paradigm]]
+[[Category:2025]]
+[[Category:Stack-based]]
+[[Category:Turing complete]]
+[[Category:No IO]]
+[[Category:Implemented]]
' |
Lines added in edit (added_lines) | [
0 => '{{infobox proglang',
1 => '|name=Reverse Polish Scheme',
2 => '|paradigms=Imperative, Stack-Based, Functional',
3 => '|author=[[User:McGoron|Peter McGoron]]',
4 => '|year=2025',
5 => '|class=Turing Complete',
6 => '|majorimpl=[https://github.com/mcgoron-peter/reverse-polish-scheme R4RS]',
7 => '|influence=Scheme, FORTH',
8 => '}}',
9 => '',
10 => ''''Reverse Polish Scheme''' (RPS) is a homoiconic, stack-based programming language with reified continuations. Its syntax is a subset of Scheme.',
11 => 'RPS can only use <code>call/cc</code> to manipulate the stack and instruction pointer. Stack operations, returns from calls, closures, delimited continuations, and all sorts of other fun things can be created using RPS's <code>call/cc</code>.',
12 => '',
13 => '== Core ==',
14 => '',
15 => 'RPS syntax is a subset of Scheme.',
16 => '',
17 => 'Line comments start with <code>;</code>. Nested block comments start with <code>#|</code> and end with <code>|#</code>. Writing a number, string, <code>#t</code>, or <code>#f</code> will push that literal value onto the stack. Writing an identifier will execute that identifier.',
18 => '',
19 => 'A literal vector is introduced with <code>#(</code> and ends with <code>)</code>. A literal list (a linked list where each list cell is a vector of two elements) starts with ( and ends with ). The empty list (nil) is represented by (). A literal identifier is introduced with <code>'</code>. (Note that lists and vectors are not quoted.)',
20 => '',
21 => 'A procedure is a linked list whose first element can be used for data storage, and whose tail is a linked list of instructions to execute. By convention, procedures that do not have any data to save in their first element have their first element be <code>#f</code>.',
22 => '',
23 => 'If the interpreter hits the end of a procedure, it will halt.',
24 => '',
25 => 'The following are the built in instructions. Instructions will execute and continue at the next instruction (exceptions are <code>call/cc</code> and <code>jump</code>). They will consume all specified arguments to them.',
26 => '',
27 => '{| class="wikitable"',
28 => '!Command',
29 => '!Description',
30 => '|-',
31 => '| style="text-align:center"| <code>proc to from call/cc</code>',
32 => '|The fundamental stack manipulator. Jump to <code>proc</code> with the continuation <code>cc</code> pushed to the stack. When <code>m cc jump</code> is called, control returns to the instruction after <code>call/cc</code>, except that the stack is the <code>m</code> values on the stack before the jump appended to the values on the stack from <code>from</code> inclusive to <code>to</code> exclusive at the site of call/cc's invocation. If <code>from</code> is <code>#f</code>, then it will capture the entire stack starting from <code>to</code> exclusive.',
33 => '|-',
34 => '| style="text-align:center"| <code>bool on-false on-true if</code>',
35 => '|If <code>bool</code> is <code>#f</code>, jump to the procedure <code>on-false</code>. Otherwise jump to the procedure <code>on-true</code>.',
36 => '|-',
37 => '| style="text-align:center"| <code>proc jump</code>',
38 => '|The next executed instruction will be the first instruction of <code>proc</code>. Note that is no return stack.',
39 => '|-',
40 => '| style="text-align:center"| <code>n vector</code>',
41 => '|Allocate a vector of <code>n</code> cells and push it to the stack.',
42 => '|-',
43 => '| style="text-align:center"| <code>vec vector-length</code>',
44 => '|Push the length in cells of <code>vec</code>. Returns <code>#f</code> if <code>vec</code> is not a vector.',
45 => '|-',
46 => '| style="text-align:center"| <code>vec n ref</code>',
47 => '|Push the <code>n</code>th cell of <code>vec</code> to the stack.',
48 => '|-',
49 => '| style="text-align:center"| <code>value n vec set!</code>',
50 => '|Set the <code>n</code>th cell of <code>vec</code> to <code>value</code>.',
51 => '|-',
52 => '| style="text-align:center"| <code>x y eqv?</code>',
53 => '|Pushes a boolean indicating if <code>x</code> and <code>y</code> are equivalent objects (i.e. the same vector or equal numbers).',
54 => '|-',
55 => '| style="text-align:center"| <code>x symbol?</code>',
56 => '|Pushes a boolean indicating if <code>x</code> is a symbol.',
57 => '|-',
58 => '| style="text-align:center" | <code>x integer?</code>',
59 => '|Pushes a boolean indicating if <code>x</code> is an exact integer.',
60 => '|-',
61 => '| style="text-align:center" | <code>x real?</code>',
62 => '|Pushes a boolean indicating if <code>x</code> is a real.',
63 => '|-',
64 => '| style="text-align:center" | <code>x y +</code>',
65 => '| Pushes <code>x + y</code>.',
66 => '|-',
67 => '| style="text-align:center" | <code>x y *</code>',
68 => '| Pushes <code>x * y</code>.',
69 => '|}',
70 => '',
71 => '== Examples ==',
72 => '',
73 => 'The stack is notated as if it was a LISP list. The first element of the list is the top of the stack.',
74 => '',
75 => 'The following code will duplicate the top of the stack.',
76 => '',
77 => ' 1 (#f jump) #f 1 call/cc',
78 => '',
79 => 'Explanation:',
80 => '',
81 => '* 1, a procedure, <code>#f</code>, 1 are pushed to the stack. The stack looks like <code>(1 #f <proc> 1 x values ...)</code>.',
82 => '* <code>call/cc</code> is invoked. It will jump to <code><proc></code> with the stack <code>(<cc> 1 x values ...)</code>.',
83 => '* <code><cc></code> is jumped into with the argument <code>1</code>. It will return to the position after the invocation of <code>call/cc</code>, pushing <code>x</code> onto a stack that was the stack at the invocation of <code>call/cc</code>, sans one element (the first 1 pushed). Hence the stack is <code>(x x values ...)</code>.',
84 => '',
85 => 'This code is normally inlined and used as a macro. A Lisp interpreter can be used as a value-level macro processor for RPS. Since there is no lexical scope, there is no need for hygienic macros. Quasiquote works well to splice in code.',
86 => '',
87 => '[[Category:Languages]]',
88 => '[[Category:Functional paradigm]]',
89 => '[[Category:2025]]',
90 => '[[Category:Stack-based]]',
91 => '[[Category:Turing complete]]',
92 => '[[Category:No IO]]',
93 => '[[Category:Implemented]]'
] |