git @ Cat's Eye Technologies Sbeezg / 265aeaa
Don't ship with (old) .beam files or generated Erlang. --HG-- rename : README => README.markdown catseye 11 years ago
6 changed file(s) with 41 addition(s) and 354 deletion(s). Raw diff Collapse all Expand all
+0
-28
README less more
0 The Sbeezg Programming Language v2002.0317
1 -------------------------------
2
3 Sbeezg is single-assignment programming taken to the extreme. Each variable
4 may only be assigned once. There is no scope. When a function is executed,
5 a new copy of it is made, with all bound variable names altered to fresh ones,
6 and this is executed instead. Execution is sequential in nature. Arguments
7 and return value are given explicitly. There are no global names; there are
8 only lambda function definitions available. There are five built-in operations.
9 For convenience, there are three data types: atoms, integers, and closures.
10
11 Here is a brief EBNF rundown of the syntax:
12
13 Appl ::= Name "=" Val "(" Val {"," Val} ")".
14 Val ::= Name | "*" Const | "{" Name {"," Name} "|" Appl {";" Appl} "|" Name "}".
15
16 A program is an application, which consists of an assignment to a new (never
17 before named in the program) variable, of a value or the result of a function
18 call. Note that the arguments of a function call may only be simple values;
19 further nested function calls are disallowed as their implicit 'piping' of
20 values from one function to the next without an intervening variable name is
21 counter to the intention of this purely single-assignment language.
22
23 This documentation isn't really complete.
24
25 Chris Pressey
26 March 17 2002
27 Winnipeg, Manitoba
0 The Sbeezg Programming Language
1 ===============================
2
3 v2002.0317
4
5 Sbeezg is single-assignment programming taken to the extreme. Each variable
6 may only be assigned once. There is no scope. When a function is executed,
7 a new copy of it is made, with all bound variable names altered to fresh ones,
8 and this is executed instead. Execution is sequential in nature. Arguments
9 and return value are given explicitly. There are no global names; there are
10 only lambda function definitions available. There are five built-in operations.
11 For convenience, there are three data types: atoms, integers, and closures.
12
13 Here is a brief EBNF rundown of the syntax:
14
15 Appl ::= Name "=" Val "(" Val {"," Val} ")".
16 Val ::= Name | "*" Const | "{" Name {"," Name} "|" Appl {";" Appl} "|" Name "}".
17
18 A program is an application, which consists of an assignment to a new (never
19 before named in the program) variable, of a value or the result of a function
20 call. Note that the arguments of a function call may only be simple values;
21 further nested function calls are disallowed as their implicit 'piping' of
22 values from one function to the next without an intervening variable name is
23 counter to the intention of this purely single-assignment language.
24
25 This documentation isn't really complete.
26
27 Chris Pressey
28 March 17 2002
29 Winnipeg, Manitoba
ebin/sbeezg.beam less more
Binary diff not shown
ebin/sbeezg_parser.beam less more
Binary diff not shown
0 #!/bin/sh
1
2 if [ ! -d ebin ]; then
3 mkdir ebin
4 fi
5 for FILE in src/*.yrl; do
6 erlc -o src $FILE
7 done
8 for FILE in src/*.erl; do
9 erlc -o ebin $FILE
10 done
+0
-326
src/sbeezg_parser.erl less more
0 -module(sbeezg_parser).
1 -define(THIS_MODULE, sbeezg_parser).
2 -export([parse/1, parse_and_scan/1, format_error/1]).
3
4 new_name({name,{atom,Line,Name}}=A) ->
5 case get(A) of
6 defn ->
7 return_error(0, io_lib:format("Name '~w' already defined", [Name]));
8 _ ->
9 put(A, defn)
10 end.
11
12 existing_name({name,{atom,Line,Name}}=A) ->
13 case get(A) of
14 undefined ->
15 return_error(0, io_lib:format("Name '~w' is not yet defined", [Name]));
16 _ ->
17 ok
18 end.
19
20 %%% END of sbeezg_parser.yrl %%%
21
22 %% ``The contents of this file are subject to the Erlang Public License,
23 %% Version 1.1, (the "License"); you may not use this file except in
24 %% compliance with the License. You should have received a copy of the
25 %% Erlang Public License along with this software. If not, it can be
26 %% retrieved via the world wide web at http://www.erlang.org/.
27 %%
28 %% Software distributed under the License is distributed on an "AS IS"
29 %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
30 %% the License for the specific language governing rights and limitations
31 %% under the License.
32 %%
33 %% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
34 %% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
35 %% AB. All Rights Reserved.''
36 %%
37 %% $Id$
38 %%
39
40 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
41 % The parser generator will insert appropriate declarations before this line.%
42
43 parse(Tokens) ->
44 case catch yeccpars1(Tokens, false, 0, [], []) of
45 error ->
46 Errorline =
47 if Tokens == [] -> 0; true -> element(2, hd(Tokens)) end,
48 {error,
49 {Errorline, ?THIS_MODULE, "syntax error at or after this line."}};
50 Other ->
51 Other
52 end.
53
54 parse_and_scan({Mod, Fun, Args}) ->
55 case apply(Mod, Fun, Args) of
56 {eof, _} ->
57 {ok, eof};
58 {error, Descriptor, _} ->
59 {error, Descriptor};
60 {ok, Tokens, _} ->
61 yeccpars1(Tokens, {Mod, Fun, Args}, 0, [], [])
62 end.
63
64 format_error(Message) ->
65 case io_lib:deep_char_list(Message) of
66 true ->
67 Message;
68 _ ->
69 io_lib:write(Message)
70 end.
71
72 % To be used in grammar files to throw an error message to the parser toplevel.
73 % Doesn't have to be exported!
74 return_error(Line, Message) ->
75 throw({error, {Line, ?THIS_MODULE, Message}}).
76
77
78 % Don't change yeccpars1/6 too much, it is called recursively by yeccpars2/8!
79 yeccpars1([Token | Tokens], Tokenizer, State, States, Vstack) ->
80 yeccpars2(State, element(1, Token), States, Vstack, Token, Tokens,
81 Tokenizer);
82 yeccpars1([], {M, F, A}, State, States, Vstack) ->
83 case catch apply(M, F, A) of
84 {eof, Endline} ->
85 {error, {Endline, ?THIS_MODULE, "end_of_file"}};
86 {error, Descriptor, Endline} ->
87 {error, Descriptor};
88 {'EXIT', Reason} ->
89 {error, {0, ?THIS_MODULE, Reason}};
90 {ok, Tokens, Endline} ->
91 case catch yeccpars1(Tokens, {M, F, A}, State, States, Vstack) of
92 error ->
93 Errorline = element(2, hd(Tokens)),
94 {error, {Errorline, ?THIS_MODULE,
95 "syntax error at or after this line."}};
96 Other ->
97 Other
98 end
99 end;
100 yeccpars1([], false, State, States, Vstack) ->
101 yeccpars2(State, '$end', States, Vstack, {'$end', 999999}, [], false).
102
103 % For internal use only.
104 yeccerror(Token) ->
105 {error,
106 {element(2, Token), ?THIS_MODULE,
107 ["syntax error before: ", yecctoken2string(Token)]}}.
108
109 yecctoken2string({atom, _, A}) -> io_lib:write(A);
110 yecctoken2string({integer,_,N}) -> io_lib:write(N);
111 yecctoken2string({float,_,F}) -> io_lib:write(F);
112 yecctoken2string({char,_,C}) -> io_lib:write_char(C);
113 yecctoken2string({var,_,V}) -> io_lib:format('~s', [V]);
114 yecctoken2string({string,_,S}) -> io_lib:write_string(S);
115 yecctoken2string({reserved_symbol, _, A}) -> io_lib:format('~w', [A]);
116 yecctoken2string({Cat, _, Val}) -> io_lib:format('~w', [Val]);
117
118 yecctoken2string({'dot', _}) -> io_lib:format('~w', ['.']);
119 yecctoken2string({'$end', _}) ->
120 [];
121 yecctoken2string({Other, _}) when atom(Other) ->
122 io_lib:format('~w', [Other]);
123 yecctoken2string(Other) ->
124 io_lib:write(Other).
125
126 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
127
128
129 yeccpars2(0, atom, __Ss, __Stack, __T, __Ts, __Tzr) ->
130 yeccpars1(__Ts, __Tzr, 3, [0 | __Ss], [__T | __Stack]);
131 yeccpars2(0, _, _, _, __T, _, _) ->
132 yeccerror(__T);
133 yeccpars2(1, '$end', _, __Stack, _, _, _) ->
134 {ok, hd(__Stack)};
135 yeccpars2(1, _, _, _, __T, _, _) ->
136 yeccerror(__T);
137 yeccpars2(2, ';', __Ss, __Stack, __T, __Ts, __Tzr) ->
138 yeccpars1(__Ts, __Tzr, 27, [2 | __Ss], [__T | __Stack]);
139 yeccpars2(2, __Cat, __Ss, [__1|__Stack], __T, __Ts, __Tzr) ->
140 __Val = {alist,__1,nil},
141 yeccpars2(yeccgoto(alist, hd(__Ss)), __Cat, __Ss, [__Val | __Stack], __T, __Ts, __Tzr);
142 yeccpars2(3, __Cat, __Ss, [__1|__Stack], __T, __Ts, __Tzr) ->
143 __Val = {name,__1},
144 yeccpars2(yeccgoto(name, hd(__Ss)), __Cat, __Ss, [__Val | __Stack], __T, __Ts, __Tzr);
145 yeccpars2(4, '=', __Ss, __Stack, __T, __Ts, __Tzr) ->
146 yeccpars1(__Ts, __Tzr, 5, [4 | __Ss], [__T | __Stack]);
147 yeccpars2(4, _, _, _, __T, _, _) ->
148 yeccerror(__T);
149 yeccpars2(5, atom, __Ss, __Stack, __T, __Ts, __Tzr) ->
150 yeccpars1(__Ts, __Tzr, 3, [5 | __Ss], [__T | __Stack]);
151 yeccpars2(5, integer, __Ss, __Stack, __T, __Ts, __Tzr) ->
152 yeccpars1(__Ts, __Tzr, 7, [5 | __Ss], [__T | __Stack]);
153 yeccpars2(5, '*', __Ss, __Stack, __T, __Ts, __Tzr) ->
154 yeccpars1(__Ts, __Tzr, 6, [5 | __Ss], [__T | __Stack]);
155 yeccpars2(5, '{', __Ss, __Stack, __T, __Ts, __Tzr) ->
156 yeccpars1(__Ts, __Tzr, 10, [5 | __Ss], [__T | __Stack]);
157 yeccpars2(5, _, _, _, __T, _, _) ->
158 yeccerror(__T);
159 yeccpars2(6, atom, __Ss, __Stack, __T, __Ts, __Tzr) ->
160 yeccpars1(__Ts, __Tzr, 26, [6 | __Ss], [__T | __Stack]);
161 yeccpars2(6, _, _, _, __T, _, _) ->
162 yeccerror(__T);
163 yeccpars2(7, __Cat, __Ss, [__1|__Stack], __T, __Ts, __Tzr) ->
164 __Val = {lit,__1},
165 yeccpars2(yeccgoto(val, hd(__Ss)), __Cat, __Ss, [__Val | __Stack], __T, __Ts, __Tzr);
166 yeccpars2(8, __Cat, __Ss, [__1|__Stack], __T, __Ts, __Tzr) ->
167 __Val = begin
168 existing_name(__1), __1
169 end,
170 yeccpars2(yeccgoto(val, hd(__Ss)), __Cat, __Ss, [__Val | __Stack], __T, __Ts, __Tzr);
171 yeccpars2(9, '(', __Ss, __Stack, __T, __Ts, __Tzr) ->
172 yeccpars1(__Ts, __Tzr, 20, [9 | __Ss], [__T | __Stack]);
173 yeccpars2(9, __Cat, __Ss, [__3,__2,__1|__Stack], __T, __Ts, __Tzr) ->
174 __Val = begin
175 new_name(__1), {assign,__1,__3}
176 end,
177 __Nss = lists:nthtail(2, __Ss),
178 yeccpars2(yeccgoto(appl, hd(__Nss)), __Cat, __Nss, [__Val | __Stack], __T, __Ts, __Tzr);
179 yeccpars2(10, atom, __Ss, __Stack, __T, __Ts, __Tzr) ->
180 yeccpars1(__Ts, __Tzr, 3, [10 | __Ss], [__T | __Stack]);
181 yeccpars2(10, _, _, _, __T, _, _) ->
182 yeccerror(__T);
183 yeccpars2(11, ',', __Ss, __Stack, __T, __Ts, __Tzr) ->
184 yeccpars1(__Ts, __Tzr, 18, [11 | __Ss], [__T | __Stack]);
185 yeccpars2(11, __Cat, __Ss, [__1|__Stack], __T, __Ts, __Tzr) ->
186 __Val = begin
187 new_name(__1), {nlist,__1,nil}
188 end,
189 yeccpars2(yeccgoto(nlist, hd(__Ss)), __Cat, __Ss, [__Val | __Stack], __T, __Ts, __Tzr);
190 yeccpars2(12, '|', __Ss, __Stack, __T, __Ts, __Tzr) ->
191 yeccpars1(__Ts, __Tzr, 13, [12 | __Ss], [__T | __Stack]);
192 yeccpars2(12, _, _, _, __T, _, _) ->
193 yeccerror(__T);
194 yeccpars2(13, atom, __Ss, __Stack, __T, __Ts, __Tzr) ->
195 yeccpars1(__Ts, __Tzr, 3, [13 | __Ss], [__T | __Stack]);
196 yeccpars2(13, _, _, _, __T, _, _) ->
197 yeccerror(__T);
198 yeccpars2(14, '|', __Ss, __Stack, __T, __Ts, __Tzr) ->
199 yeccpars1(__Ts, __Tzr, 15, [14 | __Ss], [__T | __Stack]);
200 yeccpars2(14, _, _, _, __T, _, _) ->
201 yeccerror(__T);
202 yeccpars2(15, atom, __Ss, __Stack, __T, __Ts, __Tzr) ->
203 yeccpars1(__Ts, __Tzr, 3, [15 | __Ss], [__T | __Stack]);
204 yeccpars2(15, _, _, _, __T, _, _) ->
205 yeccerror(__T);
206 yeccpars2(16, '}', __Ss, __Stack, __T, __Ts, __Tzr) ->
207 yeccpars1(__Ts, __Tzr, 17, [16 | __Ss], [__T | __Stack]);
208 yeccpars2(16, _, _, _, __T, _, _) ->
209 yeccerror(__T);
210 yeccpars2(17, __Cat, __Ss, [__7,__6,__5,__4,__3,__2,__1|__Stack], __T, __Ts, __Tzr) ->
211 __Val = {lambda,__2,__4,__6},
212 __Nss = lists:nthtail(6, __Ss),
213 yeccpars2(yeccgoto(val, hd(__Nss)), __Cat, __Nss, [__Val | __Stack], __T, __Ts, __Tzr);
214 yeccpars2(18, atom, __Ss, __Stack, __T, __Ts, __Tzr) ->
215 yeccpars1(__Ts, __Tzr, 3, [18 | __Ss], [__T | __Stack]);
216 yeccpars2(18, _, _, _, __T, _, _) ->
217 yeccerror(__T);
218 yeccpars2(19, __Cat, __Ss, [__3,__2,__1|__Stack], __T, __Ts, __Tzr) ->
219 __Val = begin
220 new_name(__1), {nlist,__1,__3}
221 end,
222 __Nss = lists:nthtail(2, __Ss),
223 yeccpars2(yeccgoto(nlist, hd(__Nss)), __Cat, __Nss, [__Val | __Stack], __T, __Ts, __Tzr);
224 yeccpars2(20, atom, __Ss, __Stack, __T, __Ts, __Tzr) ->
225 yeccpars1(__Ts, __Tzr, 3, [20 | __Ss], [__T | __Stack]);
226 yeccpars2(20, integer, __Ss, __Stack, __T, __Ts, __Tzr) ->
227 yeccpars1(__Ts, __Tzr, 7, [20 | __Ss], [__T | __Stack]);
228 yeccpars2(20, '*', __Ss, __Stack, __T, __Ts, __Tzr) ->
229 yeccpars1(__Ts, __Tzr, 6, [20 | __Ss], [__T | __Stack]);
230 yeccpars2(20, '{', __Ss, __Stack, __T, __Ts, __Tzr) ->
231 yeccpars1(__Ts, __Tzr, 10, [20 | __Ss], [__T | __Stack]);
232 yeccpars2(20, _, _, _, __T, _, _) ->
233 yeccerror(__T);
234 yeccpars2(21, ',', __Ss, __Stack, __T, __Ts, __Tzr) ->
235 yeccpars1(__Ts, __Tzr, 24, [21 | __Ss], [__T | __Stack]);
236 yeccpars2(21, __Cat, __Ss, [__1|__Stack], __T, __Ts, __Tzr) ->
237 __Val = {vlist,__1,nil},
238 yeccpars2(yeccgoto(vlist, hd(__Ss)), __Cat, __Ss, [__Val | __Stack], __T, __Ts, __Tzr);
239 yeccpars2(22, ')', __Ss, __Stack, __T, __Ts, __Tzr) ->
240 yeccpars1(__Ts, __Tzr, 23, [22 | __Ss], [__T | __Stack]);
241 yeccpars2(22, _, _, _, __T, _, _) ->
242 yeccerror(__T);
243 yeccpars2(23, __Cat, __Ss, [__6,__5,__4,__3,__2,__1|__Stack], __T, __Ts, __Tzr) ->
244 __Val = begin
245 new_name(__1), {assign,__1,__3,__5}
246 end,
247 __Nss = lists:nthtail(5, __Ss),
248 yeccpars2(yeccgoto(appl, hd(__Nss)), __Cat, __Nss, [__Val | __Stack], __T, __Ts, __Tzr);
249 yeccpars2(24, atom, __Ss, __Stack, __T, __Ts, __Tzr) ->
250 yeccpars1(__Ts, __Tzr, 3, [24 | __Ss], [__T | __Stack]);
251 yeccpars2(24, integer, __Ss, __Stack, __T, __Ts, __Tzr) ->
252 yeccpars1(__Ts, __Tzr, 7, [24 | __Ss], [__T | __Stack]);
253 yeccpars2(24, '*', __Ss, __Stack, __T, __Ts, __Tzr) ->
254 yeccpars1(__Ts, __Tzr, 6, [24 | __Ss], [__T | __Stack]);
255 yeccpars2(24, '{', __Ss, __Stack, __T, __Ts, __Tzr) ->
256 yeccpars1(__Ts, __Tzr, 10, [24 | __Ss], [__T | __Stack]);
257 yeccpars2(24, _, _, _, __T, _, _) ->
258 yeccerror(__T);
259 yeccpars2(25, __Cat, __Ss, [__3,__2,__1|__Stack], __T, __Ts, __Tzr) ->
260 __Val = {vlist,__1,__3},
261 __Nss = lists:nthtail(2, __Ss),
262 yeccpars2(yeccgoto(vlist, hd(__Nss)), __Cat, __Nss, [__Val | __Stack], __T, __Ts, __Tzr);
263 yeccpars2(26, __Cat, __Ss, [__2,__1|__Stack], __T, __Ts, __Tzr) ->
264 __Val = {lit,__2},
265 __Nss = lists:nthtail(1, __Ss),
266 yeccpars2(yeccgoto(val, hd(__Nss)), __Cat, __Nss, [__Val | __Stack], __T, __Ts, __Tzr);
267 yeccpars2(27, atom, __Ss, __Stack, __T, __Ts, __Tzr) ->
268 yeccpars1(__Ts, __Tzr, 3, [27 | __Ss], [__T | __Stack]);
269 yeccpars2(27, _, _, _, __T, _, _) ->
270 yeccerror(__T);
271 yeccpars2(28, __Cat, __Ss, [__3,__2,__1|__Stack], __T, __Ts, __Tzr) ->
272 __Val = {alist,__1,__3},
273 __Nss = lists:nthtail(2, __Ss),
274 yeccpars2(yeccgoto(alist, hd(__Nss)), __Cat, __Nss, [__Val | __Stack], __T, __Ts, __Tzr);
275 yeccpars2(__Other, _, _, _, _, _, _) ->
276 exit({parser, __Other, missing_state_in_action_table}).
277
278 yeccgoto(alist, 0) ->
279 1;
280 yeccgoto(alist, 13) ->
281 14;
282 yeccgoto(alist, 27) ->
283 28;
284 yeccgoto(appl, 0) ->
285 2;
286 yeccgoto(appl, 13) ->
287 2;
288 yeccgoto(appl, 27) ->
289 2;
290 yeccgoto(name, 0) ->
291 4;
292 yeccgoto(name, 5) ->
293 8;
294 yeccgoto(name, 10) ->
295 11;
296 yeccgoto(name, 13) ->
297 4;
298 yeccgoto(name, 15) ->
299 16;
300 yeccgoto(name, 18) ->
301 11;
302 yeccgoto(name, 20) ->
303 8;
304 yeccgoto(name, 24) ->
305 8;
306 yeccgoto(name, 27) ->
307 4;
308 yeccgoto(nlist, 10) ->
309 12;
310 yeccgoto(nlist, 18) ->
311 19;
312 yeccgoto(val, 5) ->
313 9;
314 yeccgoto(val, 20) ->
315 21;
316 yeccgoto(val, 24) ->
317 21;
318 yeccgoto(vlist, 20) ->
319 22;
320 yeccgoto(vlist, 24) ->
321 25;
322 yeccgoto(__Symbol, __State) ->
323 exit({__Symbol, __State, missing_in_goto_table}).
324
325