Skip to content

Commit cac3928

Browse files
authored
many improvements and additions (#94)
1 parent 0d4703f commit cac3928

15 files changed

+449
-24
lines changed

doc/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ SPECS = $(SPECSNUMS:%=source_%)
66

77
PDFSPECS = $(SPECS:%=%.pdf)
88

9-
HELPERS = header bnf comments intro names numbers return strings typing objects arrays interpreter lists array_support
9+
HELPERS = header bnf comments intro names numbers return strings typing objects arrays interpreter lists array_support loops boolean_operators pair_mutators
1010

1111
HELPERSTEX = $(HELPERS:%=source_%.tex)
1212

doc/source_1.tex

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@
8282

8383
\newpage
8484

85+
\input source_boolean_operators
86+
8587
\input source_return
8688

8789
\input source_names

doc/source_2.tex

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,8 @@ \section*{Changes}
9292
&& \textrm{argument expressions}
9393
\end{alignat*}
9494

95+
\input source_boolean_operators
96+
9597
\input source_return
9698

9799
\input source_names
@@ -106,5 +108,8 @@ \section*{Changes}
106108

107109
\input source_comments
108110

111+
\newpage
112+
113+
\input source_list_library
109114

110115
\end{document}

doc/source_3.tex

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,9 @@ \section*{Changes}
6262
&& && | &\quad && \textit{block}
6363
&& \textrm{block statement}\\
6464
&& && | &\quad && \textit{expression} \ \textbf{\texttt{;}}
65-
&& \textrm{expression statement} \\[1mm]
65+
&& \textrm{expression statement} \\
66+
&& && | &\quad && \epsilon
67+
&& \textrm{empty statement} \\[1mm]
6668
&& \textit{parameters} && ::= &\quad && \epsilon\ | \ \textit{name} \
6769
(\ \textbf{\texttt{,}} \ \textit{name}\ )\ \ldots
6870
&& \textrm{function parameters} \\[1mm]
@@ -130,6 +132,10 @@ \section*{Changes}
130132

131133
\newpage
132134

135+
\input source_boolean_operators
136+
137+
\input source_loops
138+
133139
\input source_return_3
134140

135141
\input source_names
@@ -150,5 +156,8 @@ \section*{Changes}
150156

151157
\input source_comments
152158

159+
\newpage
160+
161+
\input source_list_library
153162

154163
\end{document}

doc/source_4.tex

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,10 @@ \section*{Changes}
144144

145145
\newpage
146146

147+
\input source_boolean_operators
148+
149+
\input source_loops
150+
147151
\input source_return_3
148152

149153
\input source_names
@@ -168,5 +172,8 @@ \section*{Changes}
168172

169173
\input source_comments
170174

175+
\newpage
176+
177+
\input source_list_library
171178

172179
\end{document}

doc/source_array_support.tex

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ \subsection*{Array Support}
33
The following array processing function is supported:
44

55
\begin{itemize}
6-
\item \lstinline{array_length(x)}: Returns the current length of array \lstinline{x}, which is 1 plus the
6+
\item \lstinline{array_length(x)}: \textit{builtin}, returns
7+
the current length of array \lstinline{x}, which is 1 plus the
78
highest index \lstinline{i} that has been used so far in an array assignment on \lstinline{x}.
89
\end{itemize}
910

doc/source_boolean_operators.tex

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
\section*{Binary boolean operators}
2+
3+
\subsection*{Conjunction}
4+
5+
\[
6+
\textit{expression}_1 \ \textbf{\texttt{\&\&}} \ \textit{expression}_2
7+
\]
8+
stands for
9+
\[
10+
\textit{expression}_1 \ \textbf{\texttt{?}} \ \textit{expression}_2 \ \textbf{\texttt{:}}\ \textbf{\texttt{false}}
11+
\]
12+
13+
\subsection*{Disjunction}
14+
15+
\[
16+
\textit{expression}_1 \ \textbf{\texttt{||}} \ \textit{expression}_2
17+
\]
18+
stands for
19+
\[
20+
\textit{expression}_1 \ \textbf{\texttt{?}}\ \textbf{\texttt{true}}\ \textbf{\texttt{:}}\ \textit{expression}_2
21+
\]
22+
23+
24+

doc/source_interpreter.tex

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,24 @@
11
\section*{Interpreter Support}
22

33
\begin{itemize}
4-
\item \lstinline{is_number(x)}: Returns \lstinline{true} if \lstinline{x} is a number, and
4+
\item \lstinline{is_number(x)}: \textit{builtin}, returns \lstinline{true} if \lstinline{x} is a number, and
55
\lstinline{false} otherwise.
6-
\item \lstinline{is_boolean(x)}: Returns \lstinline{true} if \lstinline{x} is \lstinline{true} or \lstinline{false}, and \lstinline{false} otherwise.
7-
\item \lstinline{is_string(x)}: Returns \lstinline{true} if \lstinline{x} is a
6+
\item \lstinline{is_boolean(x)}: \textit{builtin}, returns \lstinline{true} if \lstinline{x} is \lstinline{true} or \lstinline{false}, and \lstinline{false} otherwise.
7+
\item \lstinline{is_string(x)}: \textit{builtin}, returns \lstinline{true} if \lstinline{x} is a
88
string, and \lstinline{false} otherwise.
9-
\item \lstinline{is_function(x)}: Returns \lstinline{true} if \lstinline{x} is a
9+
\item \lstinline{is_function(x)}: \textit{builtin}, returns \lstinline{true} if \lstinline{x} is a
1010
function, and \lstinline{false} otherwise.
11-
\item \lstinline{is_object(x)}: Returns \lstinline{true} if \lstinline{x} is an
11+
\item \lstinline{is_object(x)}: \textit{builtin}, returns \lstinline{true} if \lstinline{x} is an
1212
object, and \lstinline{false} otherwise. Following JavaScript, arrays are considered
1313
objects.
14-
\item \lstinline{is_array(x)}: Returns \lstinline{true} if \lstinline{x} is an
14+
\item \lstinline{is_array(x)}: \textit{builtin}, returns \lstinline{true} if \lstinline{x} is an
1515
array, and \lstinline{false} otherwise. The empty array \lstinline{[]}, also known
1616
as the empty list, is an array.
17-
\item \lstinline{parse(x)}: returns the parse tree that results from parsing
17+
\item \lstinline{parse(x)}: \textit{builtin}, returns the parse tree that results from parsing
1818
the string \lstinline{x} as a Source program.
19-
\item \lstinline{JSON.stringify(x)}: returns a string that represents the given JSON object
19+
\item \lstinline{JSON.stringify(x)}: \textit{builtin}, returns a string that represents the given JSON object
2020
\lstinline{x}.
21-
\item \lstinline{apply_in_underlying_javascript(f, xs)}: calls the function \lstinline{f}
21+
\item \lstinline{apply_in_underlying_javascript(f, xs)}: \textit{builtin}, calls the function \lstinline{f}
2222
with arguments \lstinline{xs}. For example:
2323
\begin{lstlisting}
2424
function times(x, y) {

doc/source_list_library.tex

Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
\section*{Appendix: List library}
2+
3+
Those list library functions that are not builtins are pre-declared as follows:
4+
5+
\begin{lstlisting}
6+
// is_list recurses down the list and checks that it ends with the empty list []
7+
8+
function is_list(xs) {
9+
return is_empty_list(xs) || (is_pair(xs) && is_list(tail(xs)));
10+
}
11+
12+
// equal computes the structural equality
13+
// over its arguments
14+
15+
function equal(item1, item2){
16+
return (is_pair(item1) && is_pair(item2))
17+
|| (is_empty_list(item1) && is_empty_list(item2))
18+
|| item1 === item2;
19+
}
20+
21+
// returns the length of a given argument list
22+
// assumes that the argument is a list
23+
24+
function length(xs) {
25+
return is_empty_list(xs)
26+
? 0
27+
: length(tail(xs));
28+
}
29+
30+
// map applies first arg f, assumed to be a unary function,
31+
// to the elements of the second argument, assumed to be a list.
32+
// f is applied element-by-element:
33+
// map(f, [1, [2, []]]) results in [f(1), [f(2), []]]
34+
35+
function map(f, xs) {
36+
return (is_empty_list(xs))
37+
? []
38+
: pair(f(head(xs)), map(f, tail(xs)));
39+
}
40+
41+
// build_list takes a non-negative integer n as first argument,
42+
// and a function fun as second argument.
43+
// build_list returns a list of n elements, that results from
44+
// applying fun to the numbers from 0 to n-1.
45+
46+
function build_list(n, fun){
47+
function build(i, fun, already_built) {
48+
return i < 0
49+
? already_built
50+
: build(i - 1, fun, pair(fun(i),
51+
already_built));
52+
}
53+
return build(n - 1, fun, []);
54+
}
55+
56+
// for_each applies first arg fun, assumed to be a unary function,
57+
// to the elements of the second argument, assumed to be a list.
58+
// fun is applied element-by-element:
59+
// for_each(fun, [1, [2, []]]) results in the calls fun(1) and fun(2).
60+
// for_each returns true.
61+
62+
function for_each(fun, xs) {
63+
if (is_empty_list(xs)) {
64+
return true;
65+
} else {
66+
fun(head(xs));
67+
return for_each(fun, tail(xs));
68+
}
69+
}
70+
71+
// to_string uses JavaScript's + to turn its argument into a string
72+
73+
function to_string(x) {
74+
return x + "";
75+
}
76+
77+
// list_to_string returns a string that represents the argument list.
78+
// It applies itself recursively on the elements of the given list.
79+
// When it encounters a non-list, it applies toString to it.
80+
81+
function list_to_string(xs) {
82+
return is_empty_list(xs)
83+
? "[]"
84+
: is_pair(xs)
85+
? "[" + list_to_string(head(xs)) + ","+
86+
list_to_string(tail(xs)) + "]"
87+
: to_string(xs);
88+
}
89+
90+
// reverse reverses the argument, assumed to be a list
91+
92+
function reverse(xs) {
93+
function rev(original, reversed) {
94+
return is_empty_list(original)
95+
? reversed
96+
: rev(tail(original),
97+
pair(head(original), reversed));
98+
}
99+
return rev(xs, []);
100+
}
101+
102+
// append first argument, assumed to be a list, to the second argument.
103+
// In the result, the [] at the end of the first argument list
104+
// is replaced by the second argument, regardless what the second
105+
// argument consists of.
106+
107+
function append(xs, ys) {
108+
return is_empty_list(xs)
109+
? ys
110+
: pair(head(xs),
111+
append(tail(xs), ys));
112+
}
113+
114+
// member looks for a given first-argument element in the
115+
// second argument, assumed to be a list. It returns the first
116+
// postfix sublist that starts with the given element. It returns [] if the
117+
// element does not occur in the list
118+
119+
function member(v, xs){
120+
return is_empty_list(xs)
121+
? []
122+
: (v === head(xs))
123+
? xs
124+
: member(v, tail(xs));
125+
}
126+
127+
// removes the first occurrence of a given first-argument element
128+
// in second-argument, assmed to be a list. Returns the original
129+
// list if there is no occurrence.
130+
131+
function remove(v, xs){
132+
return is_empty_list(xs)
133+
? []
134+
: v === head(xs)
135+
? tail(xs)
136+
: pair(head(xs),
137+
remove(v, tail(xs)));
138+
}
139+
140+
// Similar to remove, but removes all instances of v
141+
// instead of just the first
142+
143+
function remove_all(v, xs) {
144+
return is_empty_list(xs)
145+
? []
146+
: v === head(xs)
147+
? remove_all(v, tail(xs))
148+
: pair(head(xs),
149+
remove_all(v, tail(xs)));
150+
}
151+
152+
// filter returns the sublist of elements of the second argument
153+
// (assumed to be a list), for which the given predicate function
154+
// returns true.
155+
156+
function filter(pred, xs){
157+
return is_empty_list(xs)
158+
? xs
159+
: pred(head(xs))
160+
? pair(head(xs),
161+
filter(pred, tail(xs)))
162+
: filter(pred, tail(xs));
163+
}
164+
165+
// enumerates numbers starting from start, assumed to be a number,
166+
// using a step size of 1, until the number exceeds end, assumed
167+
// to be a number
168+
169+
function enum_list(start, end) {
170+
return start > end
171+
? []
172+
: pair(start,
173+
enum_list(start + 1, end));
174+
}
175+
176+
// Returns the item in xs (assumed to be a list) at index n,
177+
// assumed to be a non-negative integer.
178+
// Note: the first item is at position 0
179+
180+
function list_ref(xs, n) {
181+
return n === 0
182+
? head(xs)
183+
: list_ref(tail(xs), n - 1);
184+
}
185+
186+
// accumulate applies an operation op (assumed to be a binary function)
187+
// to elements of sequence (assumed to be a list) in a right-to-left order.
188+
// first apply op to the last element and initial, resulting in r1, then to
189+
// the second-last element and r1, resulting in r2, etc, and finally
190+
// to the first element and r_n-1, where n is the length of the
191+
// list.
192+
// accumulate(op, zero, list(1, 2, 3)) results in
193+
// op(1, op(2, op(3, zero)))
194+
195+
function accumulate(op, initial, sequence) {
196+
return is_empty_list(sequence)
197+
? initial
198+
: op(head(sequence),
199+
accumulate(op, initial, tail(sequence)));
200+
}
201+
\end{lstlisting}
202+
203+

doc/source_lists.tex

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,24 +3,24 @@ \subsection*{List Support}
33
The following list processing functions are supported:
44

55
\begin{itemize}
6-
\item \lstinline{pair(x, y)}: Makes a pair from \lstinline{x} and \lstinline{y}.
7-
\item \lstinline{is_pair(x)}: Returns \lstinline{true} if \lstinline{x} is a
6+
\item \lstinline{pair(x, y)}: \textit{builtin}, makes a pair from \lstinline{x} and \lstinline{y}.
7+
\item \lstinline{is_pair(x)}: \textit{builtin}, returns \lstinline{true} if \lstinline{x} is a
88
pair and \lstinline{false} otherwise.
9-
\item \lstinline{head(x)}: Returns the head (first component) of the pair \lstinline{x}.
10-
\item \lstinline{tail(x)}: Returns the tail (second component) of the
9+
\item \lstinline{head(x)}: \textit{builtin}, returns the head (first component) of the pair \lstinline{x}.
10+
\item \lstinline{tail(x)}: \textit{builtin}, returns the tail (second component) of the
1111
pair \lstinline{x}.
12-
\item \lstinline{is_empty_list(xs)}: Returns \lstinline{true} if \lstinline{xs} is the
12+
\item \lstinline{is_empty_list(xs)}: \textit{builtin}, returns \lstinline{true} if \lstinline{xs} is the
1313
empty list, and \lstinline{false} otherwise.
1414
\item \lstinline{is_list(x)}: Returns \lstinline{true} if
1515
\lstinline{x} is a list as defined in the lectures, and
1616
\lstinline{false} otherwise. Iterative process;
1717
time: $O(n)$, space: $O(1)$, where $n$ is the length of the
1818
chain of \lstinline{tail} operations that can be applied to \lstinline{x}.
19-
\item \lstinline{list(x1, x2,..., xn)}: Returns a list with $n$ elements. The
19+
\item \lstinline{list(x1, x2,..., xn)}: \textit{builtin}, returns a list with $n$ elements. The
2020
first element is \lstinline{x1}, the second \lstinline{x2}, etc. Iterative
2121
process; time: $O(n)$, space: $O(n)$, since the constructed list data structure
2222
consists of $n$ pairs, each of which takes up a constant amount of space.
23-
\item \lstinline{draw_list(x)}: Visualizes \lstinline{x} in a separate drawing
23+
\item \lstinline{draw_list(x)}: \textit{builtin}, visualizes \lstinline{x} in a separate drawing
2424
area in the Source Academy using a box-and-pointer diagram; time, space:
2525
$O(n)$, where $n$ is the number of pairs in \lstinline{x}.
2626
\item \lstinline{equal(x1, x2)}: Returns \lstinline{true} if both

0 commit comments

Comments
 (0)