-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSTEPn.while
More file actions
107 lines (96 loc) · 3.96 KB
/
STEPn.while
File metadata and controls
107 lines (96 loc) · 3.96 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
//Candidate Number: 249763
(* STEPn.while
This is the STEP macro for the universal WHILE program (self-interpreter)
ie. the STEPn.while program published on our
Canvas site:
It takes as input a list
[ CSt, DSt, St ] where
* we may assume that CSt only contains correctly encoded program statements and expressions
(so no error handling needed)
* CSt is the command stack (for program traversal)
* DSt is the data stack (intermediate results)
* St is the program store (memory) for variables
Output is a new state [ CSt1, DSt1, St1]
according to th interpretation of the topmost element of CSt.
(c) 2018-21 Bernhard Reus
This needs to be tested with the self interpreter u.while from Canvas
and the macros update.while, lookup.while, and reverse.while also from Canvas
*)
STEPn read state {
// retrieve individual arguments from list
CSt := hd state;
DSt:= hd tl state;
St:= hd tl tl state;
C:= hd CSt; // current command encoding on top of Command stack
d:= hd C; // is nil if C is a do_marker, otherwise not
if d {
// top level command executed that is of shape [op,arg1,...]
cur_op := d; // type of current command
arg := hd tl C;
arg2 := hd tl tl C;
switch cur_op {
case @quote: DSt:= cons arg DSt; CSt:= tl CSt
case @var: V := <lookup> [arg, St]; DSt := cons V DSt; CSt:= tl CSt
case @hd: CSt:= cons arg cons @doHd (tl CSt)
case @tl: CSt:= cons arg cons @doTl (tl CSt)
case @cons: CSt := cons arg2 cons arg cons @doCons (tl CSt)
case @:=: CSt := cons arg2 cons @doAsgn cons arg (tl CSt)
case @while: CSt:= cons arg cons @doWhile CSt
case @if: CSt:= cons arg cons @doIf CSt
//@concat
//taking both arguments and place it ontop of command stack.
//for operation handling, call case 8 for action
case 4: CSt := cons arg2 cons arg cons 8 (tl CSt)
//@break
//break no arguments - trying to halt the loop
case 6: CSt:= cons args cons 10 (tl CSt)
} // end switch
} else
{
// do_marker to be executed
arg:= hd DSt;
switch C {
//@doConcat
//pop second arg from data stack, concat arg with args2 using macro, place result ontop of data stack
//move to next command in the command stack
case 8: args2:= hd tl DSt; temp := <concat> [arg,args2]; DSt := cons temp (tl tl DSt);CSt := tl CSt
//@doBreak
//failed to attempt the break command
case 10: CSt := tl CSt
case @doHd: DSt:= cons (hd arg) (tl DSt); CSt:= tl CSt
case @doTl: DSt:= cons (tl arg) (tl DSt); CSt:= tl CSt
case @doCons: arg2:= hd tl DSt; DSt := cons (cons arg arg2) (tl tl DSt); CSt:= tl CSt
case @doAsgn: X := hd tl CSt; St:= <update>[X,arg,St]; DSt:= tl DSt; CSt:= tl tl CSt
case @doWhile: if arg { wc:= hd tl CSt;
CSt:= tl CSt;
B:= hd tl tl wc; // block to be added to current commands
// add the commands of B in right order onto tl Stack;
B := <reverse> B; // reverse to get the right order
while B
{ CSt:= cons (hd B) CSt;
B:= tl B
}
} else
{
CSt := tl tl CSt
} ;
DSt := tl DSt
case @doIf: ifc:= hd tl CSt;
if arg {
B:= hd tl tl ifc // then block to be added to current commands
} else {
B:= hd tl tl tl ifc // else block to be added to current commands
};
CSt:= tl tl CSt;
// add the commands of B in right order onto tl Stack;
B := <reverse> B; // reverse to get the right order
while B
{ CSt := cons (hd B) CSt;
B := tl B
};
DSt := tl DSt
} // end switch
}; // end else do_smth case
newState := [ CSt, DSt, St ]
}
write newState