aboutsummaryrefslogtreecommitdiffhomepage
path: root/mods/src
diff options
context:
space:
mode:
authorlukeg <lukeg>2003-02-21 19:01:14 +0000
committerlukeg <lukeg>2003-02-21 19:01:14 +0000
commite7d48fe500f6ed676ee1b212ebd61408bced1c5b (patch)
tree11a756c7bb4906f3e186c1cb8331cb7ed27bc69c /mods/src
downloadermacs-fork-e7d48fe500f6ed676ee1b212ebd61408bced1c5b.tar.gz
*** empty log message ***
Diffstat (limited to 'mods/src')
-rw-r--r--mods/src/Makefile12
-rw-r--r--mods/src/em_erlang.erl501
-rw-r--r--mods/src/em_erlang_scan.erl780
-rw-r--r--mods/src/em_erlang_scan.xrl135
-rw-r--r--mods/src/em_scan.erl381
-rw-r--r--mods/src/em_scheme.erl184
-rw-r--r--mods/src/em_scheme_scan.erl531
-rw-r--r--mods/src/em_scheme_scan.xrl18
-rw-r--r--mods/src/em_stdlib.erl21
-rw-r--r--mods/src/em_test_scan.erl255
-rw-r--r--mods/src/em_test_scan.xrl12
-rw-r--r--mods/src/leex.hrl217
12 files changed, 3047 insertions, 0 deletions
diff --git a/mods/src/Makefile b/mods/src/Makefile
new file mode 100644
index 0000000..8314a10
--- /dev/null
+++ b/mods/src/Makefile
@@ -0,0 +1,12 @@
+include ../../../../support/include.mk
+
+# Ermacs includes
+ERLC_FLAGS += -I ../../.. -pa ../../ebin
+
+all: $(ERL_OBJECTS)
+
+$(ERL_OBJECTS): ../../include/edit.hrl
+
+clean:
+ -rm -f $(ERL_OBJECTS)
+
diff --git a/mods/src/em_erlang.erl b/mods/src/em_erlang.erl
new file mode 100644
index 0000000..dd13e9d
--- /dev/null
+++ b/mods/src/em_erlang.erl
@@ -0,0 +1,501 @@
+%%%----------------------------------------------------------------------
+%%% File : em_erlang.erl
+%%% Author : Luke Gorrie <luke@bluetail.com>
+%%% Purpose : Erlang "Major Mode"
+%%% Created : 10 Mar 2001 by Luke Gorrie <luke@bluetail.com>
+%%%----------------------------------------------------------------------
+
+-module(em_erlang).
+-author('luke@bluetail.com').
+
+-include_lib("ermacs/include/edit.hrl").
+-import(edit_lib, [buffer/1]).
+-export([mod_init/0, erlang_mode/1, reindent_cmd/1]).
+
+-define(keymap, erlang_mode_map).
+
+%% Called by the editor when this module is load/require'd
+%%
+%% NB: may be called several times due to explicit "load" calls.
+mod_init() ->
+ catch edit_keymap:delete(?keymap),
+ init_map(),
+ edit_keymap:global_set_key("C-x e", {?MODULE, erlang_mode, []}),
+ edit_var:add_to_list(auto_mode_alist,
+ {"\.erl$$", {em_erlang, erlang_mode}}),
+ ok.
+
+erlang_mode(State) ->
+ Mode = #mode{name="Erlang",
+ id=erlang,
+ keymaps=[?keymap]},
+ Buf = buffer(State),
+ edit_buf:set_mode(Buf, Mode),
+ State.
+
+init_map() ->
+ edit_keymap:new(?keymap),
+ edit_keymap:bind_each(?keymap, bindings()).
+
+bindings() ->
+ [{"C-i", {?MODULE, reindent_cmd, []}}
+ ].
+
+reindent_cmd(State) ->
+ case scan_fun(State) of
+ no_previous_line ->
+ State;
+ Scan ->
+ B = buffer(State),
+ Indent = max(0,
+ idt(Scan)), %% + indent_cur_line_adjust(B)),
+ reindent(B, edit_lib:beginning_of_line_pos(B), Indent)
+ end.
+
+indent_cur_line_adjust(B) ->
+ case cur_line_first_token(B) of
+ nomatch ->
+ 0;
+ {match, Tok} ->
+ adjust_value(Tok)
+ end.
+
+adjust_value('when') -> 2;
+adjust_value(')') -> -1;
+adjust_value('}') -> -1;
+adjust_value(']') -> -1;
+adjust_value('>>') -> -2;
+adjust_value(_) -> 0.
+
+strip_scan(X) -> lists:flatten(strip_scan1(X)).
+
+strip_scan1([]) -> [];
+strip_scan1([{lit,_}|T]) -> ["lit "|strip_scan1(T)];
+strip_scan1([{X,Y}|T]) -> [atom_to_list(X) ++ " "|strip_scan1(T)].
+
+reindent(Buf, Pos, Lvl) ->
+ Pred = fun(C) -> (C /= $ ) and (C /= $\t) end,
+ End = max(Pos, edit_lib:find_char_forward(Buf, Pred, Pos, 1)),
+ edit_buf:replace(Buf, lists:duplicate(Lvl, $ ), Pos, End).
+
+max(X, Y) when X > Y -> X;
+max(X, Y) -> Y.
+
+min(X, Y) when X < Y -> X;
+min(X, Y) -> Y.
+
+
+beginning_of_function(State) ->
+ B = buffer(State),
+ Pos = beginning_of_function_pos(B),
+ edit_buf:move_mark(B, point, Pos).
+
+beginning_of_function_pos(B) ->
+ Point = min(edit_buf:point_max(B) - 1,
+ max(1, edit_lib:beginning_of_line_pos(B) - 1)),
+ Cord = edit_buf:get_cord(B),
+ case cord_regexp:first_match("^[a-z'$-?]", Cord, Point, backward) of
+ nomatch ->
+ 1;
+ {match, Start, End} ->
+ Start
+ end.
+
+%%% ----------------------------------------------------------------------
+%%% Indentation
+%%% ----------------------------------------------------------------------
+
+%% Calculate the indentation level for the next line of a
+%% function. `Scan' is the result of tokenising from the start of the
+%% function.
+idt(Scan) ->
+ idt(Scan, [], [], 0).
+
+%% Stack item
+-record(si,
+ {id, % icr | '->' | open
+ tok, % token
+ col, % column number of `tok'
+ old_indent % indent level when `tok' was found
+ }).
+
+%% icr means "if/case/receive(/begin/fun)" - really anything that's
+%% matched by an 'end'
+
+%% Variable names: C = Column, O = OldToken, S = Stack, I = IndentLevel
+
+%% if case receive begin
+idt([{Icr, C} | T], O, S, I)
+ when Icr == 'if'; Icr == 'case'; Icr == 'receive'; Icr == 'begin'->
+ CI = calc_clause_indent({Icr, C}, T, C),
+ idt(T, Icr, push_icr(Icr, C, I, S), CI);
+
+%% fun
+idt([{'fun', C}, {'(', OpenC} | T], O, S, I) ->
+ Rest = [{'(', OpenC} | T],
+ CI = calc_clause_indent({'fun', C}, Rest, C),
+ idt(Rest, 'fun', push_icr('fun', C, I, S), CI);
+
+%% end
+idt([{'end', C} | T], O, S, I) ->
+ case unwind_icr(S) of
+ nomatch ->
+ idt(T, 'end', [], 0);
+ {SI, S2} ->
+ idt(T, 'end', S2, SI#si.old_indent)
+ end;
+
+%% ( [ { <<
+idt([{Open, C} | T], O, S, I)
+ when Open == '('; Open == '['; Open == '{'; Open == '<<' ->
+ Width = length(atom_to_list(Open)),
+ idt(T, Open, push_open(Open, C, I, S), C+Width);
+
+%% ) ] } >>
+idt([{Close, C} | T], O, S, I)
+ when Close == ')'; Close == ']'; Close == '}'; Close == '>>' ->
+ case unwind_close(matching(Close), S) of
+ nomatch ->
+ idt(T, Close, [], 0);
+ {SI, S2} ->
+ idt(T, Close, S2, SI#si.old_indent)
+ end;
+
+%% ->
+idt([{'->', C} | T], O, S, I) ->
+ NewIndent = case unwind_icr(S) of
+ nomatch ->
+ 4;
+ {ICR_SI, ICR_S2} ->
+ ICR_SI#si.col + 8
+ end,
+ case unwind_when(S) of
+ {SI, S2} ->
+ idt(T, '->', push_arrow(C, SI#si.old_indent, S2), NewIndent);
+ nomatch ->
+ idt(T, '->', push_arrow(C, I, S), NewIndent)
+ end;
+
+%% when
+idt([{'when', C}, {Next, NextC} | T], Old, S, I) when Next /= '->' ->
+ idt(T, 'when', push_when(C, I, S), NextC);
+
+
+%% ;
+idt([{';', C} | T], O, S = [SI = #si{id='when'}|_], I) ->
+ idt(T, ';', S, I);
+
+idt([{',', C} | T], O, S = [SI = #si{id='when'}|_], I) ->
+ idt(T, ';', S, I);
+
+idt([{';', C} | T], O, S, I) ->
+ case unwind_arrow(S) of
+ nomatch ->
+ idt(T, ';', [], 0);
+ {SI, S2} ->
+ idt(T, ';', S2, SI#si.old_indent)
+ end;
+
+idt([{'when', C} | T], '\n', S, I) ->
+ idt(T, 'when', S, I+2);
+
+%% Period: end of function
+idt([{'.', C} | T], O, S, I) ->
+ idt(T, start, [], 0);
+
+%% Skip blank lines
+idt([{'\n', C}, {'\n', _} | T], O, S, I) ->
+ idt([{'\n', C} | T], O, S, I);
+
+idt([{'\n', C} | T], O, S = [#si{id=open}|_], I) ->
+ idt(T, '\n', S, I);
+
+%% End of line. The preceeding token indicates whether we need to be unwinding
+idt([{'\n', C} | T], Old, S, I)
+%%when member(Old, ?ICR_TOKENS) ->
+ when Old == '.'; Old == ';'; Old == 'of'; Old == 'begin';
+ Old == 'receive'; Old == 'if'; Old == '->'; Old == ',';
+ Old == '|' ->
+ idt(T, '\n', S, I);
+
+idt([{'\n', C} | T], O, S = [#si{id=open, old_indent=OldIndent}|_], I) ->
+ idt(T, '\n', S, OldIndent);
+
+idt([{'\n', C} | T], O, S, I) ->
+ case unwind_icr(S) of
+ nomatch ->
+ idt(T, '\n', [], 0);
+ {SI, _S2} ->
+ idt(T, '\n', S, SI#si.col)
+ end;
+
+idt([{'||', C} | T], O, S, I) ->
+ idt(T, '||', S, C + 3);
+
+%% Quotes
+
+idt([{Quote, C} | T], O, S, I) when Quote == '\'';
+ Quote == '"' ->
+ match_quote(Quote, T, S, I);
+
+%% Boring stuff
+idt([{Tok,_}|T], O, S, I) ->
+ idt(T, Tok, S, I);
+
+idt([], O, S, I) ->
+ I.
+
+push_icr(Atom, Col, Indent, Stack) ->
+ [#si{id=icr, tok=Atom, col=Col, old_indent=Indent} | Stack].
+
+push_open(Atom, Col, Indent, Stack) ->
+ [#si{id=open, tok=Atom, col=Col, old_indent=Indent} | Stack].
+
+push_arrow(Col, Indent, Stack) ->
+ [#si{id=arrow, tok='->', col=Col, old_indent=Indent} | Stack].
+
+push_when(Col, Indent, Stack) ->
+ [#si{id='when', tok='when', col=Col, old_indent=Indent} | Stack].
+
+%% Unwind the stack to find a match for a closing bracket. For a
+%% syntactically correct function, the head of the stack should always
+%% match, but otherwise I just keep unwinding to be "forgiving" -
+%% i.e. just give the wrong answer instead of an error :-)
+
+unwind_close(Tok, [SI = #si{id=open, tok=Tok} | T]) ->
+ {SI, T};
+unwind_close(Tok, [H|T]) ->
+ unwind_close(Tok, T);
+unwind_close(Tok, []) ->
+ nomatch.
+
+unwind_icr([SI = #si{id=icr} | T]) ->
+ {SI, T};
+unwind_icr([H|T]) ->
+ unwind_icr(T);
+unwind_icr([]) ->
+ nomatch.
+
+%% Returns: {SI, ICR_SI, Stack}
+unwind_arrow([SI = #si{id=arrow} | T]) ->
+ {SI, T};
+unwind_arrow([H|T]) ->
+ unwind_arrow(T);
+unwind_arrow([]) ->
+ nomatch.
+
+unwind_when([SI = #si{id='when'}|T]) ->
+ {SI, T};
+unwind_when([H|T]) ->
+ unwind_when(T);
+unwind_when([]) ->
+ nomatch.
+
+match_quote(Quote, [{'\\', _}, _ | T], S, I) ->
+ %% Something is being escaped, hop over it
+ match_quote(Quote, T, S, I);
+match_quote(Quote, [Tok = {Quote, _} | T], S, I) ->
+ idt(T, Quote, S, I);
+match_quote(Quote, [Tok|T], S, I) ->
+ match_quote(Quote, T, S, I);
+match_quote(Quote, [], S, I) ->
+ %% Out of tokens while inside a quote
+ 0.
+
+calc_clause_indent({IRF, X}, [{Next, Y}|T], I)
+ when IRF == 'if'; IRF == 'receive'; IRF == 'fun' ->
+ if
+ Next == '\n' ->
+ I + 4;
+ true ->
+ Y
+ end;
+calc_clause_indent(_, _, I) ->
+ I + 4.
+
+matching(')') -> '(';
+matching(']') -> '[';
+matching('}') -> '{';
+matching('>>') -> '<<'.
+
+%%% ----------------------------------------------------------------------
+%%% Scanner
+%%% ----------------------------------------------------------------------
+
+% make_erlang_scanner() ->
+% em_scan:make_scanner(em_erlang_scan:yystate(),
+% {em_erlang_scan, yystate},
+% {em_erlang_scan, yyaction}).
+
+% scan_fun(State) ->
+% B = buffer(State),
+% RStart = beginning_of_function_pos(B),
+% REnd = min(edit_lib:beginning_of_line_pos(B),
+% edit_buf:point_max(B) - 1),
+% Region = if
+% REnd > RStart ->
+% edit_buf:get_region(B, RStart, REnd);
+% true ->
+% ""
+% end,
+% scan(cord:new(Region)).
+
+% scan(Cord) ->
+% Scanner = make_erlang_scanner(),
+% Walker = cord:walker(Cord),
+% case em_scan:edit_scan(Scanner, Walker) of
+% {error, Rsn} ->
+% {error, Rsn};
+% {ok, Toks} ->
+% %% This module expects {Class, Column}
+% [{Type, Col} || {Type, Col, Line} <- Toks]
+% end.
+
+%%%%%%% OLD (current) SCANNER
+
+%% Token = {Class, Column}
+
+-define(MAX_TOKEN_LENGTH, 64).
+
+first_token(Str) ->
+ case scan(Str) of
+ [] ->
+ nomatch;
+ [{Tok,_}|_] ->
+ {match, Tok}
+ end.
+
+%% Returns: nomatch | {match, Token}
+cur_line_first_token(Buf) ->
+ Max = edit_buf:point_max(Buf),
+ Start = edit_lib:beginning_of_line_pos(Buf),
+ End = min(Max - 1,
+ min(Start + ?MAX_TOKEN_LENGTH,
+ edit_lib:end_of_line_pos(Buf))),
+ if
+ End > Start ->
+ Str = edit_buf:get_region(Buf, Start, End),
+ first_token(Str);
+ true ->
+ nomatch
+ end.
+
+scan_fun(State) ->
+ B = buffer(State),
+ RStart = beginning_of_function_pos(B),
+ REnd = min(edit_lib:beginning_of_line_pos(B),
+ edit_buf:point_max(B) - 1),
+ Region = if
+ REnd > RStart ->
+ edit_buf:get_region(B, RStart, REnd);
+ true ->
+ ""
+ end,
+ scan(Region).
+
+strip(X) -> [element(1, E) || E <- X].
+
+scan(Str) ->
+ S = merge_literals(scan1(Str, true, 0)),
+ S.
+
+merge_literals([]) -> [];
+merge_literals([{lit,P},{lit,_}|T]) -> merge_literals([{lit,P}|T]);
+merge_literals([H|T]) -> [H|merge_literals(T)].
+
+scan1([], _, P) ->
+ [];
+scan1([$%|T], _, P) ->
+ skip_comments(T, P);
+scan1([$$,_|T], _, P) ->
+ [{lit,P}|scan1(T, true, P+2)];
+scan1([$.,X|T], _, P) ->
+ case lists:member(X, ws()) of
+ true ->
+ [{'.',P} | scan1([X|T], true, P)];
+ false ->
+ [{lit,P}|scan1([X|T], true, P)]
+ end;
+scan1(Str, Fresh, P) ->
+ case match(Str, Fresh) of
+ nomatch when hd(Str) /= $ , hd(Str) /= $\t ->
+ [{lit,P}|scan1(tl(Str), not symchar(hd(Str)), P+1)];
+ nomatch ->
+ scan1(tl(Str), not symchar(hd(Str)), P+1);
+ {match, "\n"} ->
+ [{'\n',P} |
+ scan1(tl(Str), true, 0)];
+ {match, M} ->
+ Len = length(M),
+ Rest = lists:nthtail(Len, Str),
+ [{list_to_atom(M), P} |
+ scan1(Rest, true, P+Len)]
+ end.
+
+match(Str, true) ->
+ case match_alone(Str) of
+ nomatch ->
+ match(Str, false);
+ X ->
+ X
+ end;
+match(Str, false) ->
+ match_anywhere(Str).
+
+match_alone(Str) ->
+ match_alone(Str, alone()).
+
+match_alone(Str, [Str|_]) ->
+ {match, Str};
+match_alone(Str, [X|T]) ->
+ case lists:prefix(X, Str) of
+ true ->
+ case not symchar(lists:nth(length(X)+1, Str)) of
+ true ->
+ {match, X};
+ false ->
+ match_alone(Str, T)
+ end;
+ false ->
+ match_alone(Str, T)
+ end;
+match_alone(Str, [_|T]) ->
+ match_alone(Str, T);
+match_alone(Str, []) ->
+ nomatch.
+
+match_anywhere(Str) ->
+ match_anywhere(Str, anywhere()).
+
+match_anywhere(Str, [X|T]) ->
+ case lists:prefix(X, Str) of
+ true -> {match, X};
+ false -> match_anywhere(Str, T)
+ end;
+match_anywhere(Str, []) ->
+ nomatch.
+
+skip_comments([$\n|T], P) ->
+ scan1(T, true, P);
+skip_comments([_|T], P) ->
+ skip_comments(T, 0);
+skip_comments([], P) ->
+ [].
+
+%% Tokens that can appear anywhere
+anywhere() ->
+ ["{","}","<<",">>","(",")","[","]",";",".","->","||","|",";",",","\n",
+ "\"", "'", "\\"].
+
+%% Tokens that must appear "alone"
+alone() ->
+ ["begin", "end", "case", "if", "receive", "fun", "of", "when"].
+
+ws() -> "\r\t\n ".
+
+symchar(C) when C >= $a, C =< $z -> true;
+symchar(C) when C >= $A, C =< $Z -> true;
+symchar(C) when C >= $0, C =< $9 -> true;
+symchar($_) -> true;
+symchar(_) -> false.
+
diff --git a/mods/src/em_erlang_scan.erl b/mods/src/em_erlang_scan.erl
new file mode 100644
index 0000000..46ddba3
--- /dev/null
+++ b/mods/src/em_erlang_scan.erl
@@ -0,0 +1,780 @@
+%% THIS IS A PRE-RELEASE OF LEEX - RELEASED ONLY BECAUSE MANY PEOPLE
+%% WANTED IT - THE OFFICIAL RELEASE WILL PROVIDE A DIFFERENT INCOMPATIBLE
+%% AND BETTER INTERFACE - BE WARNED
+%% PLEASE REPORT ALL BUGS TO THE AUTHOR.
+
+-module('em_erlang_scan').
+
+-export([string/1,string/2,token/2,token/3,tokens/2,tokens/3]).
+-export([format_error/1]).
+
+%% luke
+-export([yystate/0, yystate/6, yyaction/4]).
+
+%% User code. This is placed here to allow extra attributes.
+
+-author('rv@cslab.ericsson.se').
+-copyright('Copyright (c) 1996 Ericsson Telecommunications AB').
+
+-export([reserved_word/1]).
+
+reserved_word('after') -> true;
+reserved_word('begin') -> true;
+reserved_word('case') -> true;
+reserved_word('catch') -> true;
+reserved_word('end') -> true;
+reserved_word('fun') -> true;
+reserved_word('if') -> true;
+reserved_word('let') -> true;
+reserved_word('of') -> true;
+reserved_word('query') -> true;
+reserved_word('receive') -> true;
+reserved_word('when') -> true;
+reserved_word('bnot') -> true;
+reserved_word('not') -> true;
+reserved_word('div') -> true;
+reserved_word('rem') -> true;
+reserved_word('band') -> true;
+reserved_word('and') -> true;
+reserved_word('bor') -> true;
+reserved_word('bxor') -> true;
+reserved_word('bsl') -> true;
+reserved_word('bsr') -> true;
+reserved_word('or') -> true;
+reserved_word('xor') -> true;
+reserved_word(_) -> false.
+
+base(L, Cs) ->
+ H = string:chr(Cs, $#),
+ case list_to_integer(string:substr(Cs, 1, H-1)) of
+ B when B > 16 -> {error,"illegal base"};
+ B ->
+ case base(string:substr(Cs, H+1), B, 0) of
+ error -> {error,"illegal based number"};
+ N -> {token,{integer,L,N}}
+ end
+ end.
+
+base([C|Cs], Base, SoFar) when C >= $0, C =< $9, C < Base + $0 ->
+ Next = SoFar * Base + (C - $0),
+ base(Cs, Base, Next);
+base([C|Cs], Base, SoFar) when C >= $a, C =< $f, C < Base + $a - 10 ->
+ Next = SoFar * Base + (C - $a + 10),
+ base(Cs, Base, Next);
+base([C|Cs], Base, SoFar) when C >= $A, C =< $F, C < Base + $A - 10 ->
+ Next = SoFar * Base + (C - $A + 10),
+ base(Cs, Base, Next);
+base([C|Cs], Base, SoFar) -> error;
+base([], Base, N) -> N.
+
+cc_convert([$$,$\\|Cs]) ->
+ hd(string_escape(Cs));
+cc_convert([$$,C]) -> C.
+
+string_gen([$\\|Cs]) ->
+ string_escape(Cs);
+string_gen([C|Cs]) ->
+ [C|string_gen(Cs)];
+string_gen([]) -> [].
+
+string_escape([O1,O2,O3|S]) when
+ O1 >= $0, O1 =< $7, O2 >= $0, O2 =< $7, O3 >= $0, O3 =< $7 ->
+ [(O1*8 + O2)*8 + O3 - 73*$0|string_gen(S)];
+string_escape([$^,C|Cs]) ->
+ [C band 31|string_gen(Cs)];
+string_escape([C|Cs]) when C >= 0, C =< $ ->
+ string_gen(Cs);
+string_escape([C|Cs]) ->
+ [escape_char(C)|string_gen(Cs)].
+
+escape_char($n) -> $\n; %\n = LF
+escape_char($r) -> $\r; %\r = CR
+escape_char($t) -> $\t; %\t = TAB
+escape_char($v) -> $\v; %\v = VT
+escape_char($b) -> $\b; %\b = BS
+escape_char($f) -> $\f; %\f = FF
+escape_char($e) -> $\e; %\e = ESC
+escape_char($s) -> $ ; %\s = SPC
+escape_char($d) -> $\d; %\d = DEL
+escape_char(C) -> C.
+
+
+format_error({illegal,S}) -> ["illegal characters ",io_lib:write_string(S)];
+format_error({user,S}) -> S.
+
+string(String) -> string(String, 1).
+
+string(String, Line) -> string(String, Line, String, []).
+
+%% string(InChars, Line, TokenChars, Tokens) ->
+%% {ok,Tokens,Line} | {error,ErrorInfo,Line}.
+
+string([], L, [], Ts) -> %No partial tokens!
+ {ok,yyrev(Ts),L};
+string(Ics0, L0, Tcs, Ts) ->
+ case yystate(yystate(), Ics0, L0, 0, reject, 0) of
+ {A,Alen,Ics1,L1} -> %Accepting end state
+ string_cont(Ics1, L1, yyaction(A, Alen, Tcs, L1), Ts);
+ {A,Alen,Ics1,L1,S1} -> %After an accepting state
+ string_cont(Ics1, L1, yyaction(A, Alen, Tcs, L1), Ts);
+ {reject,Alen,Tlen,Ics1,L1,S1} ->
+ {error,{L1,?MODULE,{illegal,yypre(Tcs, Tlen+1)}},L1};
+ {A,Alen,Tlen,Ics1,L1,S1} ->
+ string_cont(yysuf(Tcs, Alen), L1, yyaction(A, Alen, Tcs, L1), Ts)
+ end.
+
+%% string_cont(RestChars, Line, Token, Tokens)
+%% Test for and remove the end token wrapper.
+
+string_cont(Rest, Line, {token,T}, Ts) ->
+ string(Rest, Line, Rest, [T|Ts]);
+string_cont(Rest, Line, {end_token,T}, Ts) ->
+ string(Rest, Line, Rest, [T|Ts]);
+string_cont(Rest, Line, skip_token, Ts) ->
+ string(Rest, Line, Rest, Ts);
+string_cont(Rest, Line, {error,S}, Ts) ->
+ {error,{Line,?MODULE,{user,S}},Line}.
+
+%% token(Continuation, Chars, Line) ->
+%% {more,Continuation} | {done,ReturnVal,RestChars}.
+%% Must be careful when re-entering to append the latest characters to the
+%% after characters in an accept.
+
+token(Cont, Chars) -> token(Cont, Chars, 1).
+
+token([], Chars, Line) ->
+ token(Chars, Line, yystate(), Chars, 0, reject, 0);
+token({Line,State,Tcs,Tlen,Action,Alen}, Chars, _) ->
+ token(Chars, Line, State, Tcs ++ Chars, Tlen, Action, Alen).
+
+%% token(InChars, Line, State, TokenChars, TokenLen, Accept) ->
+%% {more,Continuation} | {done,ReturnVal,RestChars}.
+
+token(Ics0, L0, S0, Tcs, Tlen0, A0, Alen0) ->
+ case yystate(S0, Ics0, L0, Tlen0, A0, Alen0) of
+ {A1,Alen1,Ics1,L1} -> %Accepting end state
+ token_cont(Ics1, L1, yyaction(A1, Alen1, Tcs, L1));
+ {A1,Alen1,[],L1,S1} -> %After an accepting state
+ {more,{L1,S1,Tcs,Alen1,A1,Alen1}};
+ {A1,Alen1,Ics1,L1,S1} ->
+ token_cont(Ics1, L1, yyaction(A1, Alen1, Tcs, L1));
+ {A1,Alen1,Tlen1,[],L1,S1} -> %After a non-accepting state
+ {more,{L1,S1,Tcs,Tlen1,A1,Alen1}};
+ {reject,Alen1,Tlen1,eof,L1,S1} ->
+ {done,{eof,L1},[]};
+ {reject,Alen1,Tlen1,Ics1,L1,S1} ->
+ {done,{error,{L1,?MODULE,{illegal,yypre(Tcs, Tlen1+1)}},L1},Ics1};
+ {A1,Alen1,Tlen1,Ics1,L1,S1} ->
+ token_cont(yysuf(Tcs, Alen1), L1, yyaction(A1, Alen1, Tcs, L1))
+ end.
+
+%% tokens_cont(RestChars, Line, Token)
+%% Test if we have detected the end token, if so return done else continue.
+
+token_cont(Rest, Line, {token,T}) ->
+ {done,{ok,T,Line},Rest};
+token_cont(Rest, Line, {end_token,T}) ->
+ {done,{ok,T,Line},Rest};
+token_cont(Rest, Line, skip_token) ->
+ token(Rest, Line, yystate(), Rest, 0, reject, 0);
+token_cont(Rest, Line, {error,S}) ->
+ {done,{error,{Line,?MODULE,{user,S}},Line},Rest}.
+
+%% tokens(Continuation, Chars, Line) ->
+%% {more,Continuation} | {done,ReturnVal,RestChars}.
+%% Must be careful when re-entering to append the latest characters to the
+%% after characters in an accept.
+
+tokens(Cont, Chars) -> tokens(Cont, Chars, 1).
+
+tokens([], Chars, Line) ->
+ tokens(Chars, Line, yystate(), Chars, 0, [], reject, 0);
+tokens({tokens,Line,State,Tcs,Tlen,Ts,Action,Alen}, Chars, _) ->
+ tokens(Chars, Line, State, Tcs ++ Chars, Tlen, Ts, Action, Alen);
+tokens({skip_tokens,Line,State,Tcs,Tlen,Error,Action,Alen}, Chars, _) ->
+ skip_tokens(Chars, Line, State, Tcs ++ Chars, Tlen, Error, Action, Alen).
+
+%% tokens(InChars, Line, State, TokenChars, TokenLen, Tokens, Accept) ->
+%% {more,Continuation} | {done,ReturnVal,RestChars}.
+
+tokens(Ics0, L0, S0, Tcs, Tlen0, Ts, A0, Alen0) ->
+ case yystate(S0, Ics0, L0, Tlen0, A0, Alen0) of
+ {A1,Alen1,Ics1,L1} -> %Accepting end state
+ tokens_cont(Ics1, L1, yyaction(A1, Alen1, Tcs, L1), Ts);
+ {A1,Alen1,[],L1,S1} -> %After an accepting state
+ {more,{tokens,L1,S1,Tcs,Alen1,Ts,A1,Alen1}};
+ {A1,Alen1,Ics1,L1,S1} ->
+ tokens_cont(Ics1, L1, yyaction(A1, Alen1, Tcs, L1), Ts);
+ {A1,Alen1,Tlen1,[],L1,S1} -> %After a non-accepting state
+ {more,{tokens,L1,S1,Tcs,Tlen1,Ts,A1,Alen1}};
+ {reject,Alen1,Tlen1,eof,L1,S1} ->
+ {done,if Ts == [] -> {eof,L1};
+ true -> {ok,yyrev(Ts),L1} end,[]};
+ {reject,Alen1,Tlen1,Ics1,L1,S1} ->
+ skip_tokens(yysuf(Tcs, Tlen1+1), L1,
+ {L1,?MODULE,{illegal,yypre(Tcs, Tlen1+1)}});
+ {A1,Alen1,Tlen1,Ics1,L1,S1} ->
+ tokens_cont(yysuf(Tcs, Alen1), L1, yyaction(A1, Alen1, Tcs, L1), Ts)
+ end.
+
+%% tokens_cont(RestChars, Line, Token, Tokens)
+%% Test if we have detected the end token, if so return done else continue.
+
+tokens_cont(Rest, Line, {token,T}, Ts) ->
+ tokens(Rest, Line, yystate(), Rest, 0, [T|Ts], reject, 0);
+tokens_cont(Rest, Line, {end_token,T}, Ts) ->
+ {done,{ok,yyrev(Ts, [T]),Line},Rest};
+tokens_cont(Rest, Line, skip_token, Ts) ->
+ tokens(Rest, Line, yystate(), Rest, 0, Ts, reject, 0);
+tokens_cont(Rest, Line, {error,S}, Ts) ->
+ skip_tokens(Rest, Line, {Line,?MODULE,{user,S}}).
+
+%% token_skip(InChars, Line, Error) -> {done,ReturnVal,RestChars}.
+%% Skip tokens until an end token, junk everything and return the error.
+
+%%skip_tokens(Ics, Line, Error) -> {done,{error,Error,Line},Ics}.
+
+skip_tokens(Ics, Line, Error) ->
+ skip_tokens(Ics, Line, yystate(), Ics, 0, Error, reject, 0).
+
+%% skip_tokens(InChars, Line, State, TokenChars, TokenLen, Tokens, Accept) ->
+%% {more,Continuation} | {done,ReturnVal,RestChars}.
+
+skip_tokens(Ics0, L0, S0, Tcs, Tlen0, Error, A0, Alen0) ->
+ case yystate(S0, Ics0, L0, Tlen0, A0, Alen0) of
+ {A1,Alen1,Ics1,L1} -> %Accepting end state
+ skip_cont(Ics1, L1, yyaction(A1, Alen1, Tcs, L1), Error);
+ {A1,Alen1,[],L1,S1} -> %After an accepting state
+ {more,{skip_tokens,L1,S1,Tcs,Alen1,Error,A1,Alen1}};
+ {A1,Alen1,Ics1,L1,S1} ->
+ skip_cont(Ics1, L1, yyaction(A1, Alen1, Tcs, L1), Error);
+ {A1,Alen1,Tlen1,[],L1,S1} -> %After a non-accepting state
+ {more,{skip_tokens,L1,S1,Tcs,Tlen1,Error,A1,Alen1}};
+ {reject,Alen1,Tlen1,eof,L1,S1} ->
+ {done,{error,Error,L1},[]};
+ {reject,Alen1,Tlen1,Ics1,L1,S1} ->
+ skip_tokens(yysuf(Tcs, Tlen1), L1, Error);
+ {A1,Alen1,Tlen1,Ics1,L1,S1} ->
+ skip_cont(yysuf(Tcs, Alen1), L1, yyaction(A1, Alen1, Tcs, L1), Error)
+ end.
+
+%% skip_cont(RestChars, Line, Token, Error)
+%% Test if we have detected the end token, if so return done else continue.
+
+skip_cont(Rest, Line, {token,T}, Error) ->
+ skip_tokens(Rest, Line, yystate(), Rest, 0, Error, reject, 0);
+skip_cont(Rest, Line, {end_token,T}, Error) ->
+ {done,{error,Error,Line},Rest};
+skip_cont(Rest, Line, {error,S}, Error) ->
+ skip_tokens(Rest, Line, yystate(), Rest, 0, Error, reject, 0);
+skip_cont(Rest, Line, skip_token, Error) ->
+ skip_tokens(Rest, Line, yystate(), Rest, 0, Error, reject, 0).
+
+yyrev(L) -> yyrev(L, []).
+
+yyrev([H|T], Acc) -> yyrev(T, [H|Acc]);
+yyrev([], Acc) -> Acc.
+
+yypre([H|T], N) when N > 0 -> [H|yypre(T, N-1)];
+yypre(L, N) -> [].
+
+yysuf([H|T], N) when N > 0 -> yysuf(T, N-1);
+yysuf(L, 0) -> L.
+
+yysplit(L, N) -> yysplit(L, N, []).
+yysplit([H|T], N, Acc) when N > 0 -> yysplit(T, N-1, [H|Acc]);
+yysplit(L, 0, Acc) -> {lists:reverse(Acc), L}.
+
+%% yystate() -> InitialState.
+%% yystate(State, InChars, Line, Token, ) ->
+%% {Action, AcceptLength, RestChars, Line} | Accepting end state
+%% {Action, AcceptLength, RestChars, Line, State} | Accepting state
+%% {Action, AcceptLength, TokLength, RestChars, Line, State} |
+%% {reject, AcceptLength, TokLength, RestChars, Line, State}.
+%% Generated state transition functions.
+
+yystate() -> 49.
+
+yystate(52, [C|Ics], Line, Tlen, Action, Alen) when C >= $\000, C =< $\t ->
+ yystate(52, Ics, Line, Tlen+1, 21, Tlen);
+yystate(52, [C|Ics], Line, Tlen, Action, Alen) when C >= $\v, C =< $ÿ ->
+ yystate(52, Ics, Line, Tlen+1, 21, Tlen);
+yystate(52, Ics, Line, Tlen, Action, Alen) ->
+ {21,Tlen,Ics,Line,52};
+yystate(51, Ics, Line, Tlen, Action, Alen) ->
+ {19,Tlen,Ics,Line};
+yystate(50, Ics, Line, Tlen, Action, Alen) ->
+ {20,Tlen,Ics,Line};
+yystate(49, [$\n|Ics], Line, Tlen, Action, Alen) ->
+ yystate(45, Ics, Line+1, Tlen+1, Action, Alen);
+yystate(49, [$!|Ics], Line, Tlen, Action, Alen) ->
+ yystate(51, Ics, Line, Tlen+1, Action, Alen);
+yystate(49, [$"|Ics], Line, Tlen, Action, Alen) ->
+ yystate(41, Ics, Line, Tlen+1, Action, Alen);
+yystate(49, [$#|Ics], Line, Tlen, Action, Alen) ->
+ yystate(51, Ics, Line, Tlen+1, Action, Alen);
+yystate(49, [$$|Ics], Line, Tlen, Action, Alen) ->
+ yystate(21, Ics, Line, Tlen+1, Action, Alen);
+yystate(49, [$%|Ics], Line, Tlen, Action, Alen) ->
+ yystate(2, Ics, Line, Tlen+1, Action, Alen);
+yystate(49, [$'|Ics], Line, Tlen, Action, Alen) ->
+ yystate(6, Ics, Line, Tlen+1, Action, Alen);
+yystate(49, [$+|Ics], Line, Tlen, Action, Alen) ->
+ yystate(26, Ics, Line, Tlen+1, Action, Alen);
+yystate(49, [$,|Ics], Line, Tlen, Action, Alen) ->
+ yystate(51, Ics, Line, Tlen+1, Action, Alen);
+yystate(49, [$-|Ics], Line, Tlen, Action, Alen) ->
+ yystate(34, Ics, Line, Tlen+1, Action, Alen);
+yystate(49, [$.|Ics], Line, Tlen, Action, Alen) ->
+ yystate(46, Ics, Line, Tlen+1, Action, Alen);
+yystate(49, [$/|Ics], Line, Tlen, Action, Alen) ->
+ yystate(48, Ics, Line, Tlen+1, Action, Alen);
+yystate(49, [$:|Ics], Line, Tlen, Action, Alen) ->
+ yystate(8, Ics, Line, Tlen+1, Action, Alen);
+yystate(49, [$;|Ics], Line, Tlen, Action, Alen) ->
+ yystate(51, Ics, Line, Tlen+1, Action, Alen);
+yystate(49, [$<|Ics], Line, Tlen, Action, Alen) ->
+ yystate(0, Ics, Line, Tlen+1, Action, Alen);
+yystate(49, [$=|Ics], Line, Tlen, Action, Alen) ->
+ yystate(7, Ics, Line, Tlen+1, Action, Alen);
+yystate(49, [$>|Ics], Line, Tlen, Action, Alen) ->
+ yystate(35, Ics, Line, Tlen+1, Action, Alen);
+yystate(49, [$?|Ics], Line, Tlen, Action, Alen) ->
+ yystate(51, Ics, Line, Tlen+1, Action, Alen);
+yystate(49, [$[|Ics], Line, Tlen, Action, Alen) ->
+ yystate(51, Ics, Line, Tlen+1, Action, Alen);
+yystate(49, [$]|Ics], Line, Tlen, Action, Alen) ->
+ yystate(51, Ics, Line, Tlen+1, Action, Alen);
+yystate(49, [$_|Ics], Line, Tlen, Action, Alen) ->
+ yystate(43, Ics, Line, Tlen+1, Action, Alen);
+yystate(49, [C|Ics], Line, Tlen, Action, Alen) when C >= $\000, C =< $\t ->
+ yystate(45, Ics, Line, Tlen+1, Action, Alen);
+yystate(49, [C|Ics], Line, Tlen, Action, Alen) when C >= $\v, C =< $\s ->
+ yystate(45, Ics, Line, Tlen+1, Action, Alen);
+yystate(49, [C|Ics], Line, Tlen, Action, Alen) when C >= $(, C =< $* ->
+ yystate(51, Ics, Line, Tlen+1, Action, Alen);
+yystate(49, [C|Ics], Line, Tlen, Action, Alen) when C >= $0, C =< $9 ->
+ yystate(40, Ics, Line, Tlen+1, Action, Alen);
+yystate(49, [C|Ics], Line, Tlen, Action, Alen) when C >= $A, C =< $Z ->
+ yystate(43, Ics, Line, Tlen+1, Action, Alen);
+yystate(49, [C|Ics], Line, Tlen, Action, Alen) when C >= $a, C =< $z ->
+ yystate(47, Ics, Line, Tlen+1, Action, Alen);
+yystate(49, [C|Ics], Line, Tlen, Action, Alen) when C >= ${, C =< $} ->
+ yystate(51, Ics, Line, Tlen+1, Action, Alen);
+yystate(49, Ics, Line, Tlen, Action, Alen) ->
+ {Action,Alen,Tlen,Ics,Line,49};
+yystate(48, [$=|Ics], Line, Tlen, Action, Alen) ->
+ yystate(44, Ics, Line, Tlen+1, 19, Tlen);
+yystate(48, Ics, Line, Tlen, Action, Alen) ->
+ {19,Tlen,Ics,Line,48};
+yystate(47, [$_|Ics], Line, Tlen, Action, Alen) ->
+ yystate(47, Ics, Line, Tlen+1, 3, Tlen);
+yystate(47, [C|Ics], Line, Tlen, Action, Alen) when C >= $0, C =< $9 ->
+ yystate(47, Ics, Line, Tlen+1, 3, Tlen);
+yystate(47, [C|Ics], Line, Tlen, Action, Alen) when C >= $@, C =< $Z ->
+ yystate(47, Ics, Line, Tlen+1, 3, Tlen);
+yystate(47, [C|Ics], Line, Tlen, Action, Alen) when C >= $a, C =< $z ->
+ yystate(47, Ics, Line, Tlen+1, 3, Tlen);
+yystate(47, Ics, Line, Tlen, Action, Alen) ->
+ {3,Tlen,Ics,Line,47};
+yystate(46, [$\n|Ics], Line, Tlen, Action, Alen) ->
+ yystate(50, Ics, Line+1, Tlen+1, 19, Tlen);
+yystate(46, [$%|Ics], Line, Tlen, Action, Alen) ->
+ yystate(52, Ics, Line, Tlen+1, 19, Tlen);
+yystate(46, [C|Ics], Line, Tlen, Action, Alen) when C >= $\000, C =< $\t ->
+ yystate(50, Ics, Line, Tlen+1, 19, Tlen);
+yystate(46, [C|Ics], Line, Tlen, Action, Alen) when C >= $\v, C =< $\s ->
+ yystate(50, Ics, Line, Tlen+1, 19, Tlen);
+yystate(46, Ics, Line, Tlen, Action, Alen) ->
+ {19,Tlen,Ics,Line,46};
+yystate(45, [$\n|Ics], Line, Tlen, Action, Alen) ->
+ yystate(45, Ics, Line+1, Tlen+1, 22, Tlen);
+yystate(45, [C|Ics], Line, Tlen, Action, Alen) when C >= $\000, C =< $\t ->
+ yystate(45, Ics, Line, Tlen+1, 22, Tlen);
+yystate(45, [C|Ics], Line, Tlen, Action, Alen) when C >= $\v, C =< $\s ->
+ yystate(45, Ics, Line, Tlen+1, 22, Tlen);
+yystate(45, Ics, Line, Tlen, Action, Alen) ->
+ {22,Tlen,Ics,Line,45};
+yystate(44, Ics, Line, Tlen, Action, Alen) ->
+ {13,Tlen,Ics,Line};
+yystate(43, [$_|Ics], Line, Tlen, Action, Alen) ->
+ yystate(43, Ics, Line, Tlen+1, 4, Tlen);
+yystate(43, [C|Ics], Line, Tlen, Action, Alen) when C >= $0, C =< $9 ->
+ yystate(43, Ics, Line, Tlen+1, 4, Tlen);
+yystate(43, [C|Ics], Line, Tlen, Action, Alen) when C >= $@, C =< $Z ->
+ yystate(43, Ics, Line, Tlen+1, 4, Tlen);
+yystate(43, [C|Ics], Line, Tlen, Action, Alen) when C >= $a, C =< $z ->
+ yystate(43, Ics, Line, Tlen+1, 4, Tlen);
+yystate(43, Ics, Line, Tlen, Action, Alen) ->
+ {4,Tlen,Ics,Line,43};
+yystate(42, Ics, Line, Tlen, Action, Alen) ->
+ {8,Tlen,Ics,Line};
+yystate(41, [$\n|Ics], Line, Tlen, Action, Alen) ->
+ yystate(41, Ics, Line+1, Tlen+1, Action, Alen);
+yystate(41, [$"|Ics], Line, Tlen, Action, Alen) ->
+ yystate(37, Ics, Line, Tlen+1, Action, Alen);
+yystate(41, [$\\|Ics], Line, Tlen, Action, Alen) ->
+ yystate(33, Ics, Line, Tlen+1, Action, Alen);
+yystate(41, [C|Ics], Line, Tlen, Action, Alen) when C >= $\000, C =< $\t ->
+ yystate(41, Ics, Line, Tlen+1, Action, Alen);
+yystate(41, [C|Ics], Line, Tlen, Action, Alen) when C >= $\v, C =< $! ->
+ yystate(41, Ics, Line, Tlen+1, Action, Alen);
+yystate(41, [C|Ics], Line, Tlen, Action, Alen) when C >= $#, C =< $[ ->
+ yystate(41, Ics, Line, Tlen+1, Action, Alen);
+yystate(41, [C|Ics], Line, Tlen, Action, Alen) when C >= $], C =< $ÿ ->
+ yystate(41, Ics, Line, Tlen+1, Action, Alen);
+yystate(41, Ics, Line, Tlen, Action, Alen) ->
+ {Action,Alen,Tlen,Ics,Line,41};
+yystate(40, [$#|Ics], Line, Tlen, Action, Alen) ->
+ yystate(36, Ics, Line, Tlen+1, 2, Tlen);
+yystate(40, [$.|Ics], Line, Tlen, Action, Alen) ->
+ yystate(28, Ics, Line, Tlen+1, 2, Tlen);
+yystate(40, [C|Ics], Line, Tlen, Action, Alen) when C >= $0, C =< $9 ->
+ yystate(40, Ics, Line, Tlen+1, 2, Tlen);
+yystate(40, Ics, Line, Tlen, Action, Alen) ->
+ {2,Tlen,Ics,Line,40};
+yystate(39, Ics, Line, Tlen, Action, Alen) ->
+ {14,Tlen,Ics,Line};
+yystate(38, Ics, Line, Tlen, Action, Alen) ->
+ {18,Tlen,Ics,Line};
+yystate(37, Ics, Line, Tlen, Action, Alen) ->
+ {5,Tlen,Ics,Line};
+yystate(36, [C|Ics], Line, Tlen, Action, Alen) when C >= $0, C =< $9 ->
+ yystate(32, Ics, Line, Tlen+1, Action, Alen);
+yystate(36, [C|Ics], Line, Tlen, Action, Alen) when C >= $A, C =< $F ->
+ yystate(32, Ics, Line, Tlen+1, Action, Alen);
+yystate(36, [C|Ics], Line, Tlen, Action, Alen) when C >= $a, C =< $f ->
+ yystate(32, Ics, Line, Tlen+1, Action, Alen);
+yystate(36, Ics, Line, Tlen, Action, Alen) ->
+ {Action,Alen,Tlen,Ics,Line,36};
+yystate(35, [$=|Ics], Line, Tlen, Action, Alen) ->
+ yystate(39, Ics, Line, Tlen+1, 19, Tlen);
+yystate(35, Ics, Line, Tlen, Action, Alen) ->
+ {19,Tlen,Ics,Line,35};
+yystate(34, [$-|Ics], Line, Tlen, Action, Alen) ->
+ yystate(38, Ics, Line, Tlen+1, 19, Tlen);
+yystate(34, [$>|Ics], Line, Tlen, Action, Alen) ->
+ yystate(42, Ics, Line, Tlen+1, 19, Tlen);
+yystate(34, Ics, Line, Tlen, Action, Alen) ->
+ {19,Tlen,Ics,Line,34};
+yystate(33, [$\n|Ics], Line, Tlen, Action, Alen) ->
+ yystate(41, Ics, Line+1, Tlen+1, Action, Alen);
+yystate(33, [$"|Ics], Line, Tlen, Action, Alen) ->
+ yystate(29, Ics, Line, Tlen+1, Action, Alen);
+yystate(33, [$\\|Ics], Line, Tlen, Action, Alen) ->
+ yystate(33, Ics, Line, Tlen+1, Action, Alen);
+yystate(33, [$]|Ics], Line, Tlen, Action, Alen) ->
+ yystate(41, Ics, Line, Tlen+1, Action, Alen);
+yystate(33, [$^|Ics], Line, Tlen, Action, Alen) ->
+ yystate(25, Ics, Line, Tlen+1, Action, Alen);
+yystate(33, [C|Ics], Line, Tlen, Action, Alen) when C >= $\000, C =< $\t ->
+ yystate(41, Ics, Line, Tlen+1, Action, Alen);
+yystate(33, [C|Ics], Line, Tlen, Action, Alen) when C >= $\v, C =< $! ->
+ yystate(41, Ics, Line, Tlen+1, Action, Alen);
+yystate(33, [C|Ics], Line, Tlen, Action, Alen) when C >= $#, C =< $[ ->
+ yystate(41, Ics, Line, Tlen+1, Action, Alen);
+yystate(33, [C|Ics], Line, Tlen, Action, Alen) when C >= $_, C =< $ÿ ->
+ yystate(41, Ics, Line, Tlen+1, Action, Alen);
+yystate(33, Ics, Line, Tlen, Action, Alen) ->
+ {Action,Alen,Tlen,Ics,Line,33};
+yystate(32, [C|Ics], Line, Tlen, Action, Alen) when C >= $0, C =< $9 ->
+ yystate(32, Ics, Line, Tlen+1, 1, Tlen);
+yystate(32, [C|Ics], Line, Tlen, Action, Alen) when C >= $A, C =< $F ->
+ yystate(32, Ics, Line, Tlen+1, 1, Tlen);
+yystate(32, [C|Ics], Line, Tlen, Action, Alen) when C >= $a, C =< $f ->
+ yystate(32, Ics, Line, Tlen+1, 1, Tlen);
+yystate(32, Ics, Line, Tlen, Action, Alen) ->
+ {1,Tlen,Ics,Line,32};
+yystate(31, Ics, Line, Tlen, Action, Alen) ->
+ {11,Tlen,Ics,Line};
+yystate(30, Ics, Line, Tlen, Action, Alen) ->
+ {17,Tlen,Ics,Line};
+yystate(29, [$\n|Ics], Line, Tlen, Action, Alen) ->
+ yystate(41, Ics, Line+1, Tlen+1, 5, Tlen);
+yystate(29, [$"|Ics], Line, Tlen, Action, Alen) ->
+ yystate(37, Ics, Line, Tlen+1, 5, Tlen);
+yystate(29, [$\\|Ics], Line, Tlen, Action, Alen) ->
+ yystate(33, Ics, Line, Tlen+1, 5, Tlen);
+yystate(29, [C|Ics], Line, Tlen, Action, Alen) when C >= $\000, C =< $\t ->
+ yystate(41, Ics, Line, Tlen+1, 5, Tlen);
+yystate(29, [C|Ics], Line, Tlen, Action, Alen) when C >= $\v, C =< $! ->
+ yystate(41, Ics, Line, Tlen+1, 5, Tlen);
+yystate(29, [C|Ics], Line, Tlen, Action, Alen) when C >= $#, C =< $[ ->
+ yystate(41, Ics, Line, Tlen+1, 5, Tlen);
+yystate(29, [C|Ics], Line, Tlen, Action, Alen) when C >= $], C =< $ÿ ->
+ yystate(41, Ics, Line, Tlen+1, 5, Tlen);
+yystate(29, Ics, Line, Tlen, Action, Alen) ->
+ {5,Tlen,Ics,Line,29};
+yystate(28, [C|Ics], Line, Tlen, Action, Alen) when C >= $0, C =< $9 ->
+ yystate(24, Ics, Line, Tlen+1, Action, Alen);
+yystate(28, Ics, Line, Tlen, Action, Alen) ->
+ {Action,Alen,Tlen,Ics,Line,28};
+yystate(27, Ics, Line, Tlen, Action, Alen) ->
+ {15,Tlen,Ics,Line};
+yystate(26, [$+|Ics], Line, Tlen, Action, Alen) ->
+ yystate(30, Ics, Line, Tlen+1, 19, Tlen);
+yystate(26, Ics, Line, Tlen, Action, Alen) ->
+ {19,Tlen,Ics,Line,26};
+yystate(25, [$\n|Ics], Line, Tlen, Action, Alen) ->
+ yystate(41, Ics, Line+1, Tlen+1, Action, Alen);
+yystate(25, [$"|Ics], Line, Tlen, Action, Alen) ->
+ yystate(29, Ics, Line, Tlen+1, Action, Alen);
+yystate(25, [$\\|Ics], Line, Tlen, Action, Alen) ->
+ yystate(33, Ics, Line, Tlen+1, Action, Alen);
+yystate(25, [C|Ics], Line, Tlen, Action, Alen) when C >= $\000, C =< $\t ->
+ yystate(41, Ics, Line, Tlen+1, Action, Alen);
+yystate(25, [C|Ics], Line, Tlen, Action, Alen) when C >= $\v, C =< $! ->
+ yystate(41, Ics, Line, Tlen+1, Action, Alen);
+yystate(25, [C|Ics], Line, Tlen, Action, Alen) when C >= $#, C =< $[ ->
+ yystate(41, Ics, Line, Tlen+1, Action, Alen);
+yystate(25, [C|Ics], Line, Tlen, Action, Alen) when C >= $], C =< $ÿ ->
+ yystate(41, Ics, Line, Tlen+1, Action, Alen);
+yystate(25, Ics, Line, Tlen, Action, Alen) ->
+ {Action,Alen,Tlen,Ics,Line,25};
+yystate(24, [$E|Ics], Line, Tlen, Action, Alen) ->
+ yystate(12, Ics, Line, Tlen+1, 0, Tlen);
+yystate(24, [$e|Ics], Line, Tlen, Action, Alen) ->
+ yystate(12, Ics, Line, Tlen+1, 0, Tlen);
+yystate(24, [C|Ics], Line, Tlen, Action, Alen) when C >= $0, C =< $9 ->
+ yystate(24, Ics, Line, Tlen+1, 0, Tlen);
+yystate(24, Ics, Line, Tlen, Action, Alen) ->
+ {0,Tlen,Ics,Line,24};
+yystate(23, Ics, Line, Tlen, Action, Alen) ->
+ {12,Tlen,Ics,Line};
+yystate(22, [$\n|Ics], Line, Tlen, Action, Alen) ->
+ yystate(6, Ics, Line+1, Tlen+1, Action, Alen);
+yystate(22, [$'|Ics], Line, Tlen, Action, Alen) ->
+ yystate(18, Ics, Line, Tlen+1, Action, Alen);
+yystate(22, [$\\|Ics], Line, Tlen, Action, Alen) ->
+ yystate(14, Ics, Line, Tlen+1, Action, Alen);
+yystate(22, [C|Ics], Line, Tlen, Action, Alen) when C >= $\000, C =< $\t ->
+ yystate(6, Ics, Line, Tlen+1, Action, Alen);
+yystate(22, [C|Ics], Line, Tlen, Action, Alen) when C >= $\v, C =< $& ->
+ yystate(6, Ics, Line, Tlen+1, Action, Alen);
+yystate(22, [C|Ics], Line, Tlen, Action, Alen) when C >= $(, C =< $[ ->
+ yystate(6, Ics, Line, Tlen+1, Action, Alen);
+yystate(22, [C|Ics], Line, Tlen, Action, Alen) when C >= $], C =< $ÿ ->
+ yystate(6, Ics, Line, Tlen+1, Action, Alen);
+yystate(22, Ics, Line, Tlen, Action, Alen) ->
+ {Action,Alen,Tlen,Ics,Line,22};
+yystate(21, [$\\|Ics], Line, Tlen, Action, Alen) ->
+ yystate(17, Ics, Line, Tlen+1, Action, Alen);
+yystate(21, [C|Ics], Line, Tlen, Action, Alen) when C >= $\000, C =< $\t ->
+ yystate(5, Ics, Line, Tlen+1, Action, Alen);
+yystate(21, [C|Ics], Line, Tlen, Action, Alen) when C >= $\v, C =< $[ ->
+ yystate(5, Ics, Line, Tlen+1, Action, Alen);
+yystate(21, [C|Ics], Line, Tlen, Action, Alen) when C >= $], C =< $ÿ ->
+ yystate(5, Ics, Line, Tlen+1, Action, Alen);
+yystate(21, Ics, Line, Tlen, Action, Alen) ->
+ {Action,Alen,Tlen,Ics,Line,21};
+yystate(20, [C|Ics], Line, Tlen, Action, Alen) when C >= $0, C =< $9 ->
+ yystate(16, Ics, Line, Tlen+1, Action, Alen);
+yystate(20, Ics, Line, Tlen, Action, Alen) ->
+ {Action,Alen,Tlen,Ics,Line,20};
+yystate(19, [$=|Ics], Line, Tlen, Action, Alen) ->
+ yystate(23, Ics, Line, Tlen+1, Action, Alen);
+yystate(19, Ics, Line, Tlen, Action, Alen) ->
+ {Action,Alen,Tlen,Ics,Line,19};
+yystate(18, [$\n|Ics], Line, Tlen, Action, Alen) ->
+ yystate(6, Ics, Line+1, Tlen+1, 6, Tlen);
+yystate(18, [$'|Ics], Line, Tlen, Action, Alen) ->
+ yystate(10, Ics, Line, Tlen+1, 6, Tlen);
+yystate(18, [$\\|Ics], Line, Tlen, Action, Alen) ->
+ yystate(14, Ics, Line, Tlen+1, 6, Tlen);
+yystate(18, [C|Ics], Line, Tlen, Action, Alen) when C >= $\000, C =< $\t ->
+ yystate(6, Ics, Line, Tlen+1, 6, Tlen);
+yystate(18, [C|Ics], Line, Tlen, Action, Alen) when C >= $\v, C =< $& ->
+ yystate(6, Ics, Line, Tlen+1, 6, Tlen);
+yystate(18, [C|Ics], Line, Tlen, Action, Alen) when C >= $(, C =< $[ ->
+ yystate(6, Ics, Line, Tlen+1, 6, Tlen);
+yystate(18, [C|Ics], Line, Tlen, Action, Alen) when C >= $], C =< $ÿ ->
+ yystate(6, Ics, Line, Tlen+1, 6, Tlen);
+yystate(18, Ics, Line, Tlen, Action, Alen) ->
+ {6,Tlen,Ics,Line,18};
+yystate(17, [$^|Ics], Line, Tlen, Action, Alen) ->
+ yystate(1, Ics, Line, Tlen+1, 7, Tlen);
+yystate(17, [C|Ics], Line, Tlen, Action, Alen) when C >= $\000, C =< $\t ->
+ yystate(5, Ics, Line, Tlen+1, 7, Tlen);
+yystate(17, [C|Ics], Line, Tlen, Action, Alen) when C >= $\v, C =< $/ ->
+ yystate(5, Ics, Line, Tlen+1, 7, Tlen);
+yystate(17, [C|Ics], Line, Tlen, Action, Alen) when C >= $0, C =< $7 ->
+ yystate(13, Ics, Line, Tlen+1, 7, Tlen);
+yystate(17, [C|Ics], Line, Tlen, Action, Alen) when C >= $8, C =< $] ->
+ yystate(5, Ics, Line, Tlen+1, 7, Tlen);
+yystate(17, [C|Ics], Line, Tlen, Action, Alen) when C >= $_, C =< $ÿ ->
+ yystate(5, Ics, Line, Tlen+1, 7, Tlen);
+yystate(17, Ics, Line, Tlen, Action, Alen) ->
+ {7,Tlen,Ics,Line,17};
+yystate(16, [C|Ics], Line, Tlen, Action, Alen) when C >= $0, C =< $9 ->
+ yystate(16, Ics, Line, Tlen+1, 0, Tlen);
+yystate(16, Ics, Line, Tlen, Action, Alen) ->
+ {0,Tlen,Ics,Line,16};
+yystate(15, Ics, Line, Tlen, Action, Alen) ->
+ {10,Tlen,Ics,Line};
+yystate(14, [$\n|Ics], Line, Tlen, Action, Alen) ->
+ yystate(6, Ics, Line+1, Tlen+1, Action, Alen);
+yystate(14, [$'|Ics], Line, Tlen, Action, Alen) ->
+ yystate(18, Ics, Line, Tlen+1, Action, Alen);
+yystate(14, [$\\|Ics], Line, Tlen, Action, Alen) ->
+ yystate(14, Ics, Line, Tlen+1, Action, Alen);
+yystate(14, [$]|Ics], Line, Tlen, Action, Alen) ->
+ yystate(6, Ics, Line, Tlen+1, Action, Alen);
+yystate(14, [$^|Ics], Line, Tlen, Action, Alen) ->
+ yystate(22, Ics, Line, Tlen+1, Action, Alen);
+yystate(14, [C|Ics], Line, Tlen, Action, Alen) when C >= $\000, C =< $\t ->
+ yystate(6, Ics, Line, Tlen+1, Action, Alen);
+yystate(14, [C|Ics], Line, Tlen, Action, Alen) when C >= $\v, C =< $& ->
+ yystate(6, Ics, Line, Tlen+1, Action, Alen);
+yystate(14, [C|Ics], Line, Tlen, Action, Alen) when C >= $(, C =< $[ ->
+ yystate(6, Ics, Line, Tlen+1, Action, Alen);
+yystate(14, [C|Ics], Line, Tlen, Action, Alen) when C >= $_, C =< $ÿ ->
+ yystate(6, Ics, Line, Tlen+1, Action, Alen);
+yystate(14, Ics, Line, Tlen, Action, Alen) ->
+ {Action,Alen,Tlen,Ics,Line,14};
+yystate(13, [C|Ics], Line, Tlen, Action, Alen) when C >= $0, C =< $7 ->
+ yystate(9, Ics, Line, Tlen+1, 7, Tlen);
+yystate(13, Ics, Line, Tlen, Action, Alen) ->
+ {7,Tlen,Ics,Line,13};
+yystate(12, [$+|Ics], Line, Tlen, Action, Alen) ->
+ yystate(20, Ics, Line, Tlen+1, Action, Alen);
+yystate(12, [$-|Ics], Line, Tlen, Action, Alen) ->
+ yystate(20, Ics, Line, Tlen+1, Action, Alen);
+yystate(12, [C|Ics], Line, Tlen, Action, Alen) when C >= $0, C =< $9 ->
+ yystate(16, Ics, Line, Tlen+1, Action, Alen);
+yystate(12, Ics, Line, Tlen, Action, Alen) ->
+ {Action,Alen,Tlen,Ics,Line,12};
+yystate(11, [$=|Ics], Line, Tlen, Action, Alen) ->
+ yystate(15, Ics, Line, Tlen+1, Action, Alen);
+yystate(11, Ics, Line, Tlen, Action, Alen) ->
+ {Action,Alen,Tlen,Ics,Line,11};
+yystate(10, Ics, Line, Tlen, Action, Alen) ->
+ {6,Tlen,Ics,Line};
+yystate(9, [C|Ics], Line, Tlen, Action, Alen) when C >= $0, C =< $7 ->
+ yystate(5, Ics, Line, Tlen+1, Action, Alen);
+yystate(9, Ics, Line, Tlen, Action, Alen) ->
+ {Action,Alen,Tlen,Ics,Line,9};
+yystate(8, [$-|Ics], Line, Tlen, Action, Alen) ->
+ yystate(4, Ics, Line, Tlen+1, 19, Tlen);
+yystate(8, Ics, Line, Tlen, Action, Alen) ->
+ {19,Tlen,Ics,Line,8};
+yystate(7, [$/|Ics], Line, Tlen, Action, Alen) ->
+ yystate(11, Ics, Line, Tlen+1, 19, Tlen);
+yystate(7, [$:|Ics], Line, Tlen, Action, Alen) ->
+ yystate(19, Ics, Line, Tlen+1, 19, Tlen);
+yystate(7, [$<|Ics], Line, Tlen, Action, Alen) ->
+ yystate(27, Ics, Line, Tlen+1, 19, Tlen);
+yystate(7, [$=|Ics], Line, Tlen, Action, Alen) ->
+ yystate(31, Ics, Line, Tlen+1, 19, Tlen);
+yystate(7, Ics, Line, Tlen, Action, Alen) ->
+ {19,Tlen,Ics,Line,7};
+yystate(6, [$\n|Ics], Line, Tlen, Action, Alen) ->
+ yystate(6, Ics, Line+1, Tlen+1, Action, Alen);
+yystate(6, [$'|Ics], Line, Tlen, Action, Alen) ->
+ yystate(10, Ics, Line, Tlen+1, Action, Alen);
+yystate(6, [$\\|Ics], Line, Tlen, Action, Alen) ->
+ yystate(14, Ics, Line, Tlen+1, Action, Alen);
+yystate(6, [C|Ics], Line, Tlen, Action, Alen) when C >= $\000, C =< $\t ->
+ yystate(6, Ics, Line, Tlen+1, Action, Alen);
+yystate(6, [C|Ics], Line, Tlen, Action, Alen) when C >= $\v, C =< $& ->
+ yystate(6, Ics, Line, Tlen+1, Action, Alen);
+yystate(6, [C|Ics], Line, Tlen, Action, Alen) when C >= $(, C =< $[ ->
+ yystate(6, Ics, Line, Tlen+1, Action, Alen);
+yystate(6, [C|Ics], Line, Tlen, Action, Alen) when C >= $], C =< $ÿ ->
+ yystate(6, Ics, Line, Tlen+1, Action, Alen);
+yystate(6, Ics, Line, Tlen, Action, Alen) ->
+ {Action,Alen,Tlen,Ics,Line,6};
+yystate(5, Ics, Line, Tlen, Action, Alen) ->
+ {7,Tlen,Ics,Line};
+yystate(4, Ics, Line, Tlen, Action, Alen) ->
+ {9,Tlen,Ics,Line};
+yystate(3, Ics, Line, Tlen, Action, Alen) ->
+ {16,Tlen,Ics,Line};
+yystate(2, [C|Ics], Line, Tlen, Action, Alen) when C >= $\000, C =< $\t ->
+ yystate(2, Ics, Line, Tlen+1, 23, Tlen);
+yystate(2, [C|Ics], Line, Tlen, Action, Alen) when C >= $\v, C =< $ÿ ->
+ yystate(2, Ics, Line, Tlen+1, 23, Tlen);
+yystate(2, Ics, Line, Tlen, Action, Alen) ->
+ {23,Tlen,Ics,Line,2};
+yystate(1, [C|Ics], Line, Tlen, Action, Alen) when C >= $\000, C =< $\t ->
+ yystate(5, Ics, Line, Tlen+1, 7, Tlen);
+yystate(1, [C|Ics], Line, Tlen, Action, Alen) when C >= $\v, C =< $ÿ ->
+ yystate(5, Ics, Line, Tlen+1, 7, Tlen);
+yystate(1, Ics, Line, Tlen, Action, Alen) ->
+ {7,Tlen,Ics,Line,1};
+yystate(0, [$=|Ics], Line, Tlen, Action, Alen) ->
+ yystate(3, Ics, Line, Tlen+1, 19, Tlen);
+yystate(0, Ics, Line, Tlen, Action, Alen) ->
+ {19,Tlen,Ics,Line,0};
+yystate(S, Ics, Line, Tlen, Action, Alen) ->
+ {Action,Alen,Tlen,Ics,Line,S}.
+
+
+%% yyaction(Action, TokenLength, TokenChars, Line) ->
+%% {token,Token} | {end_token, Token} | skip_token | {error,String}.
+%% Generated action function.
+
+yyaction(0, YYlen, YYtcs, YYline) ->
+ YYtext = yypre(YYtcs, YYlen),
+ {token,{float,YYline,list_to_float(YYtext)}};
+yyaction(1, YYlen, YYtcs, YYline) ->
+ YYtext = yypre(YYtcs, YYlen),
+ base(YYline,YYtext);
+yyaction(2, YYlen, YYtcs, YYline) ->
+ YYtext = yypre(YYtcs, YYlen),
+ {token,{integer,YYline,list_to_integer(YYtext)}};
+yyaction(3, YYlen, YYtcs, YYline) ->
+ YYtext = yypre(YYtcs, YYlen),
+ Atom = list_to_atom(YYtext),
+ {token,case reserved_word(Atom) of
+ true ->
+ {Atom,YYline};
+ false ->
+ {atom,YYline,Atom}
+ end};
+yyaction(4, YYlen, YYtcs, YYline) ->
+ YYtext = yypre(YYtcs, YYlen),
+ {token,{var,YYline,list_to_atom(YYtext)}};
+yyaction(5, YYlen, YYtcs, YYline) ->
+ YYtext = yypre(YYtcs, YYlen),
+ S = lists:sublist(YYtext,2,length(YYtext) - 2),
+ {token,{string,YYline,string_gen(S)}};
+yyaction(6, YYlen, YYtcs, YYline) ->
+ YYtext = yypre(YYtcs, YYlen),
+ S = lists:sublist(YYtext,2,length(YYtext) - 2),
+ {token,{atom,YYline,list_to_atom(string_gen(S))}};
+yyaction(7, YYlen, YYtcs, YYline) ->
+ YYtext = yypre(YYtcs, YYlen),
+ {token,{integer,YYline,cc_convert(YYtext)}};
+yyaction(8, YYlen, YYtcs, YYline) ->
+ {token,{'->',YYline}};
+yyaction(9, YYlen, YYtcs, YYline) ->
+ {token,{':-',YYline}};
+yyaction(10, YYlen, YYtcs, YYline) ->
+ {token,{'=/=',YYline}};
+yyaction(11, YYlen, YYtcs, YYline) ->
+ {token,{'==',YYline}};
+yyaction(12, YYlen, YYtcs, YYline) ->
+ {token,{'=:=',YYline}};
+yyaction(13, YYlen, YYtcs, YYline) ->
+ {token,{'/=',YYline}};
+yyaction(14, YYlen, YYtcs, YYline) ->
+ {token,{'>=',YYline}};
+yyaction(15, YYlen, YYtcs, YYline) ->
+ {token,{'=<',YYline}};
+yyaction(16, YYlen, YYtcs, YYline) ->
+ {token,{'<=',YYline}};
+yyaction(17, YYlen, YYtcs, YYline) ->
+ {token,{'++',YYline}};
+yyaction(18, YYlen, YYtcs, YYline) ->
+ {token,{'--',YYline}};
+yyaction(19, YYlen, YYtcs, YYline) ->
+ YYtext = yypre(YYtcs, YYlen),
+ {token,{list_to_atom(YYtext),YYline}};
+yyaction(20, YYlen, YYtcs, YYline) ->
+ {end_token,{dot,YYline}};
+yyaction(21, YYlen, YYtcs, YYline) ->
+ {end_token,{dot,YYline}};
+yyaction(22, YYlen, YYtcs, YYline) -> skip_token;
+yyaction(23, YYlen, YYtcs, YYline) ->
+ skip_token;
+yyaction(_, _, _, _) -> error.
diff --git a/mods/src/em_erlang_scan.xrl b/mods/src/em_erlang_scan.xrl
new file mode 100644
index 0000000..572cb29
--- /dev/null
+++ b/mods/src/em_erlang_scan.xrl
@@ -0,0 +1,135 @@
+%% Token Definitions for Erlang.
+
+Definitions.
+O = [0-7]
+D = [0-9]
+H = [0-9a-fA-F]
+A = [a-z_A-Z@0-9]
+WS = [\000-\s]
+
+Rules.
+{D}+\.{D}+((E|e)(\+|\-)?{D}+)? :
+ {token,{float,YYline,list_to_float(YYtext)}}.
+{D}+#{H}+ : base(YYline, YYtext).
+{D}+ : {token,{integer,YYline,list_to_integer(YYtext)}}.
+[a-z]{A}* : Atom = list_to_atom(YYtext),
+ {token,case reserved_word(Atom) of
+ true -> {Atom,YYline};
+ false -> {atom,YYline,Atom}
+ end}.
+[_A-Z]{A}* : {token,{var,YYline,list_to_atom(YYtext)}}.
+"(\\\^.|\\.|[^"])*" :
+ %% Strip quotes.
+ S = lists:sublist(YYtext, 2, length(YYtext) - 2),
+ {token,{string,YYline,string_gen(S)}}.
+'(\\\^.|\\.|[^'])*' :
+ %% Strip quotes.
+ S = lists:sublist(YYtext, 2, length(YYtext) - 2),
+ {token,{atom,YYline,list_to_atom(string_gen(S))}}.
+\$(\\{O}{O}{O}|\\\^.|\\.|.) :
+ {token,{integer,YYline,cc_convert(YYtext)}}.
+-> : {token,{'->',YYline}}.
+:- : {token,{':-',YYline}}.
+=/= : {token,{'=/=',YYline}}.
+== : {token,{'==',YYline}}.
+=:= : {token,{'=:=',YYline}}.
+/= : {token,{'/=',YYline}}.
+>= : {token,{'>=',YYline}}.
+=< : {token,{'=<',YYline}}.
+<= : {token,{'<=',YYline}}.
+\+\+ : {token,{'++',YYline}}.
+-- : {token,{'--',YYline}}.
+[!?/;:,.*+#()[\]|<>={}-] :
+ {token,{list_to_atom(YYtext),YYline}}.
+\.{WS} : {end_token,{dot,YYline}}.
+\.%.* : {end_token,{dot,YYline}}. %Must special case this
+{WS}+ : . %No token returned, eqivalent
+\%.* : skip_token. % to 'skip_token'
+
+Erlang code.
+
+-author('rv@cslab.ericsson.se').
+-copyright('Copyright (c) 1996 Ericsson Telecommunications AB').
+
+-export([reserved_word/1]).
+
+reserved_word('after') -> true;
+reserved_word('begin') -> true;
+reserved_word('case') -> true;
+reserved_word('catch') -> true;
+reserved_word('end') -> true;
+reserved_word('fun') -> true;
+reserved_word('if') -> true;
+reserved_word('let') -> true;
+reserved_word('of') -> true;
+reserved_word('query') -> true;
+reserved_word('receive') -> true;
+reserved_word('when') -> true;
+reserved_word('bnot') -> true;
+reserved_word('not') -> true;
+reserved_word('div') -> true;
+reserved_word('rem') -> true;
+reserved_word('band') -> true;
+reserved_word('and') -> true;
+reserved_word('bor') -> true;
+reserved_word('bxor') -> true;
+reserved_word('bsl') -> true;
+reserved_word('bsr') -> true;
+reserved_word('or') -> true;
+reserved_word('xor') -> true;
+reserved_word(_) -> false.
+
+base(L, Cs) ->
+ H = string:chr(Cs, $#),
+ case list_to_integer(string:substr(Cs, 1, H-1)) of
+ B when B > 16 -> {error,"illegal base"};
+ B ->
+ case base(string:substr(Cs, H+1), B, 0) of
+ error -> {error,"illegal based number"};
+ N -> {token,{integer,L,N}}
+ end
+ end.
+
+base([C|Cs], Base, SoFar) when C >= $0, C =< $9, C < Base + $0 ->
+ Next = SoFar * Base + (C - $0),
+ base(Cs, Base, Next);
+base([C|Cs], Base, SoFar) when C >= $a, C =< $f, C < Base + $a - 10 ->
+ Next = SoFar * Base + (C - $a + 10),
+ base(Cs, Base, Next);
+base([C|Cs], Base, SoFar) when C >= $A, C =< $F, C < Base + $A - 10 ->
+ Next = SoFar * Base + (C - $A + 10),
+ base(Cs, Base, Next);
+base([C|Cs], Base, SoFar) -> error;
+base([], Base, N) -> N.
+
+cc_convert([$$,$\\|Cs]) ->
+ hd(string_escape(Cs));
+cc_convert([$$,C]) -> C.
+
+string_gen([$\\|Cs]) ->
+ string_escape(Cs);
+string_gen([C|Cs]) ->
+ [C|string_gen(Cs)];
+string_gen([]) -> [].
+
+string_escape([O1,O2,O3|S]) when
+ O1 >= $0, O1 =< $7, O2 >= $0, O2 =< $7, O3 >= $0, O3 =< $7 ->
+ [(O1*8 + O2)*8 + O3 - 73*$0|string_gen(S)];
+string_escape([$^,C|Cs]) ->
+ [C band 31|string_gen(Cs)];
+string_escape([C|Cs]) when C >= 0, C =< $ ->
+ string_gen(Cs);
+string_escape([C|Cs]) ->
+ [escape_char(C)|string_gen(Cs)].
+
+escape_char($n) -> $\n; %\n = LF
+escape_char($r) -> $\r; %\r = CR
+escape_char($t) -> $\t; %\t = TAB
+escape_char($v) -> $\v; %\v = VT
+escape_char($b) -> $\b; %\b = BS
+escape_char($f) -> $\f; %\f = FF
+escape_char($e) -> $\e; %\e = ESC
+escape_char($s) -> $ ; %\s = SPC
+escape_char($d) -> $\d; %\d = DEL
+escape_char(C) -> C.
+
diff --git a/mods/src/em_scan.erl b/mods/src/em_scan.erl
new file mode 100644
index 0000000..5467423
--- /dev/null
+++ b/mods/src/em_scan.erl
@@ -0,0 +1,381 @@
+%%%----------------------------------------------------------------------
+%%% File : em_scan.erl
+%%% Author : Luke Gorrie <luke@bluetail.com>
+%%% Purpose : Scanner for leex-style DFAs.
+%%% Created : 1 May 2001 by Luke Gorrie <luke@bluetail.com>
+%%%----------------------------------------------------------------------
+
+-module(em_scan).
+-author('luke@bluetail.com').
+
+-record(scanner, {initial_state, dfa_fn, action_fn}).
+
+%% Token record. The actual lexeme, if returned by the scanner, is
+%% discarded - all that's taken from the user-written "actions" is the
+%% token type. Instead we just keep the start/finish positions in a
+%% cord.
+%%
+%% Not retaining line/column information. Hopefully that's convenient
+%% to derive later.
+-record(token,
+ {
+ %% type chosen by scanner. There is also a special type:
+ %% 'em_skipped', when the scanner returns 'skip_token' but
+ %% we record it anyway.
+ type,
+ %% start position in cord
+ start,
+ %% finish position in cord (point *after* the last character)
+ finish,
+ %% number of characters beyond the end of the lexeme that
+ %% the scanner state machine examined, recorded to track
+ %% dependency
+ lookahead,
+ %% for book keeping, saying whether the token is known to
+ %% need re-scanning
+ dirty=false
+ }).
+
+-compile(export_all).
+%%-export([Function/Arity, ...]).
+
+%% Bogus line number to pass to leex/yecc, because I don't want to
+%% track lines at this low level. It's not safe to use an atom, but
+%% hopefully -42 looks deliberate enough to prompt a grep :-)
+
+-define(line, -42). %% Confusing number appearing where line # should be :-)
+
+make_scanner(State0, DFA, Action) ->
+ #scanner{initial_state=State0,
+ dfa_fn=DFA,
+ action_fn=Action}.
+
+make_scheme_scanner() -> make_leex_scanner(em_scheme_scan).
+make_erlang_scanner() -> make_leex_scanner(em_erlang_scan).
+make_test_scanner() -> make_leex_scanner(em_test_scan).
+
+make_leex_scanner(Mod) ->
+ make_scanner(Mod:yystate(),
+ {Mod, yystate},
+ {Mod, yyaction}).
+
+scan_annotation(Scanner, _S0, Cord, RText, Start, End) ->
+ Walker = cord:walker(Cord),
+ case edit_scan(Scanner, Walker) of
+ {ok, Toks} ->
+ {ok, Toks};
+ {error, Reason} ->
+ {ok, bad_scan}
+ end.
+
+test_test(Str) ->
+ case test_string(Str) of
+ {ok, Toks} ->
+ {ok, lists:map(fun(T) -> element(1, T) end,
+ Toks)};
+ X ->
+ X
+ end.
+
+erlang_test(Str) ->
+ case erlang_string(Str) of
+ {ok, Toks} ->
+ {ok, lists:map(fun(T) -> element(1, T) end,
+ Toks)};
+ X ->
+ X
+ end.
+
+scheme_test(Str) ->
+ case scheme_string(Str) of
+ {ok, Toks} ->
+ {ok, lists:map(fun(T) -> element(1, T) end,
+ Toks)};
+ X ->
+ X
+ end.
+
+test_string(Str) ->
+ Cord = list_to_binary(Str),
+ Scan = make_test_scanner(),
+ edit_scan(Scan, cord:walker(Cord)).
+
+scheme_string(Str) ->
+ Cord = list_to_binary(Str),
+ Scan = make_scheme_scanner(),
+ edit_scan(Scan, cord:walker(Cord)).
+
+erlang_string(Str) ->
+ Cord = list_to_binary(Str),
+ Scan = make_erlang_scanner(),
+ edit_scan(Scan, cord:walker(Cord)).
+
+%% Returns: {ok, [#token]} | {error, Reason}
+edit_scan(Scn, Walker) ->
+ edit_scan(Scn, Walker, 1, []).
+
+edit_scan(Scn, Walker, Pos) ->
+ edit_scan(Scn, Walker, 1, []).
+
+edit_scan(Scn, W0, Pos, Acc) ->
+ case token(Scn, W0) of
+ {done, eof} ->
+ {ok, lists:reverse(Acc)};
+ {done, Result, W1} ->
+ Token = make_token(Pos, Result),
+ edit_scan(Scn, W1, Token#token.finish, [Token|Acc]);
+ {error, Reason} ->
+ {error, Reason}
+ end.
+
+make_skipped_token(Pos, Len, LookAhead) ->
+ #token{type=em_skipped,
+ start=Pos,
+ finish=Pos+Len,
+ lookahead=LookAhead}.
+
+% tokens(Scn, Walker) ->
+% tokens(Scn, Walker, []).
+
+% tokens(Scn, W0, Acc) ->
+% case token(Scn, W0) of
+% {done, {ok, T, Acs}, W1} ->
+% tokens(Scn, W1, [T|Acc]);
+% {done, {skip_token, Acs}, W1} ->
+% tokens(Scn, W1, Acc);
+% {done, eof} ->
+% {ok, lists:reverse(Acc)};
+% {error, Reason} ->
+% {error, Reason}
+% end.
+
+token(Scn, Walker) ->
+ State0 = Scn#scanner.initial_state,
+ token(Scn, Walker, State0, [], 0, reject, 0).
+
+token(Scn, W0, S0, Tcs0, Tlen0, A0, Alen0) ->
+ ActionF = Scn#scanner.action_fn,
+ DFA_F = Scn#scanner.dfa_fn,
+ {Ics, Tcs1, W1} = case cord:walker_next(W0) of
+ {done, WEOF} ->
+ {eof, Tcs0, WEOF};
+ {Ch, Wnext} ->
+ {[Ch], [Ch|Tcs0], Wnext}
+ end,
+ case DFA_F(S0, Ics, ?line, Tlen0, A0, Alen0) of
+ {A1,Alen1,[],L1} -> % accepting end state
+ TcsFwd = lists:reverse(Tcs1),
+ token_cont(Scn,TcsFwd,W1,[],ActionF(A1,Alen1,TcsFwd,?line));
+ {A1,Alen1,[],L1,S1} -> % after accepting state
+ token(Scn,W1,S1,Tcs1,Alen1,A1,Alen1);
+ {A1,Alen1,Ics1,L1,S1} -> % accepting state with leftover
+ % chars.. sounds like a time
+ % to act.
+ TcsFwd = lists:reverse(Tcs1),
+ Acs = yypre(TcsFwd, Alen1),
+ token_cont(Scn,Acs,W1,Ics1,ActionF(A1,Alen1,TcsFwd,?line));
+ {A1,Alen1,Tlen1,[],L1,S1} -> % after a non-accepting state
+ token(Scn,W1,S1,Tcs1,Tlen1,A1,Alen1);
+ {reject,Alen1,Tlen1,eof,L1,S1} ->
+ {done,eof};
+ {reject,Alen1,Tlen1,Ics1,L1,S1} ->
+ {done,
+ {error,{illegal,yypre(Tcs1, Tlen1+1)}},
+ Ics1};
+ {A1,Alen1,Tlen1,Ics1,L1,S1} ->
+ TcsFwd = lists:reverse(Tcs1),
+ {Acs, Rest} = yysplit(TcsFwd, Alen1),
+ token_cont(Scn,Acs,W1,Rest,ActionF(A1,Alen1,TcsFwd,?line))
+ end.
+
+token_cont(Scn, Acs, W, Rest, {token, T}) ->
+ {done, {ok, T, Acs, length_of(Rest)}, pushback(W, Rest)};
+token_cont(Scn, Acs, W, Rest, {end_token, T}) ->
+ {done, {ok, T, Acs, length_of(Rest)}, pushback(W, Rest)};
+token_cont(Scn, Acs, W, Rest, SkipToken) ->
+ {done, {skip_token, Acs, length_of(Rest)}, pushback(W, Rest)};
+token_cont(Scn, Acs, W, Rest, {error, S}) ->
+ {done, {error, {user,S}}, pushback(W, Rest)}.
+
+adjust_pos(C, L, [$\n|T]) -> adjust_pos(0, L+1, T);
+adjust_pos(C, L, [_|T]) -> adjust_pos(C+1, L, T);
+adjust_pos(C, L, []) -> {C, L}.
+
+length_of(eof) -> 0;
+length_of(List) -> length(List).
+
+pushback(W, eof) ->
+ W;
+pushback(W, Chars) ->
+ lists:foldr(fun(C, Wn) -> cord:walker_push(C, Wn) end,
+ W,
+ Chars).
+
+yyrev([H|T], Acc) -> yyrev(T, [H|Acc]);
+yyrev([], Acc) -> Acc.
+
+yypre([H|T], N) when N > 0 -> [H|yypre(T, N-1)];
+yypre(L, N) -> [].
+
+yysuf([H|T], N) when N > 0 -> yysuf(T, N-1);
+yysuf(L, 0) -> L.
+
+yysplit(L, N) -> yysplit(L, N, []).
+yysplit([H|T], N, Acc) when N > 0 -> yysplit(T, N-1, [H|Acc]);
+yysplit(L, 0, Acc) -> {lists:reverse(Acc), L}.
+
+%%%%%
+%% Experimentation with incremental parsing (working)
+
+str0() -> "-bar+ +foo-".
+toks0() ->
+ {ok, Toks} = test_string(str0()),
+ Toks.
+
+%% Hand-hacked version of Toks0 with the space character deleted and
+%% its token marked as dirty. When properly re-scanned, this should be
+%% the same as toks1 (basis of the test case)
+dirty_toks() -> [OK_A,OK_B,OK_C,Changed0|Following0] = toks0(),
+ Changed1 = Changed0#token{dirty=true},
+ Following1 = lists:map(fun(T) ->
+ Start = T#token.start,
+ Finish = T#token.finish,
+ T#token{start=Start-1,
+ finish=Finish-1}
+ end,
+ Following0),
+ [OK_A,OK_B,OK_C,Changed1|Following1].
+
+%% for: "bar++foo"
+%% The space has been changed (now length 0) and is marked dirty.
+str1() -> str0() -- " ".
+toks1() ->
+ {ok, Toks} = test_string(str1()),
+ Toks.
+
+rescan_test() ->
+ Scn = make_test_scanner(),
+ Dirty = mark_dirty(dirty_toks()),
+ Cord = cord:new(str1()),
+ Result = rescan(Scn, Cord, Dirty),
+ {Result == toks1(), Result, Dirty}.
+
+%% What should happen with this simple algorithm and test case:
+%% 1. We see that a token is dirty.
+%% 2. We scan backwards for dependencies (by seeing what has a look-ahead
+%% that reaches the dirty token, or another token that does, etc)
+%% 3. From the earliest dependency, we start re-scanning everything
+%% until we scan a token which leaves the state of the lexer the same as
+%% it was previously (i.e. so the following token is known to be
+%% unchanged)
+%%
+%% So, how is the state of the lexer defined? In leex it seems to me
+%% that the internal scanner state is always the same at the start of
+%% each token (barring anything magical done in actions - which for
+%% now I ignore). So, I think it's safe to assume that a token will be
+%% unchanged if both the chars in its lexeme and the ones reached by
+%% its look-ahead are the same. For "tricky stuff" it may be necessary
+%% to capture the process dictionary and include (some of) it in the
+%% state.
+%%
+%% So I will terminate when I reach a token beyond the changed text
+%% which is starting in the same place.
+%%
+%% NB: We shouldn't need to go *too* far backwards when marking
+%% dependencies in languages I can think of, because of common
+%% zero-lookahead tokens like: \n , ; ( ) ...etc and most other
+%% tokens will just be 1-lookahead.
+
+re_lex(Toks0) ->
+ Toks1 = mark_dirty(Toks0).
+
+mark_dirty(Toks) ->
+ mark_dirty(Toks, []).
+
+mark_dirty([H|T], Acc) when H#token.dirty == true ->
+ mark_dirty1([H|T], H#token.start, Acc);
+mark_dirty([H|T], Acc) ->
+ mark_dirty(T, [H|Acc]);
+mark_dirty([], Acc) ->
+ lists:reverse(Acc).
+
+mark_dirty1(OK, DirtyPos, Toks0) ->
+ F = fun(Tok, DP) ->
+ case (Tok#token.finish-1) + Tok#token.lookahead of
+ P when P >= DP ->
+ {Tok#token{dirty=true},
+ Tok#token.start};
+ _ ->
+ {Tok, DP}
+ end
+ end,
+ {Toks1, _} = lists:mapfoldl(F, DirtyPos, Toks0),
+ lists:reverse(Toks1) ++ OK.
+
+%% Rescan dirty tokens.
+rescan(Scn, Cord, []) ->
+ [];
+rescan(Scn, Cord, [H|T]) when H#token.dirty == false ->
+ [H|rescan(Scn, Cord, T)];
+rescan(Scn, Cord, [H|T]) when H#token.dirty == true ->
+ Pos = H#token.start,
+ {_, Region} = cord:split(Cord, Pos-1),
+ Walker = cord:walker(Region),
+ rescan_dirty(Scn, Walker, Pos, [H|T]).
+
+%% rescan_dirty(Toks)
+%%
+%% The first token is dirty. Scan until we get back to a sane state
+rescan_dirty(Scn, W0, Pos, [Tok|Toks]) ->
+ Start = Tok#token.start,
+ io:format("(Pos = ~p) Rescanning ~p~n", [Pos, Tok]),
+ case token(Scn, W0) of
+ {done, eof} ->
+ [];
+ {done, Result, W1} ->
+ Token = make_token(Pos, Result),
+ [Token|rescan_dirty_cont(Scn, W1, Token#token.finish, Toks)];
+ {error, Reason} ->
+ %% FIXME: should make an error-token and carry on
+ {error, Reason}
+ end.
+
+rescan_dirty_cont(Scn, W, Pos, []) ->
+ [];
+rescan_dirty_cont(Scn, W, Pos, Rest) ->
+ Next = hd(Rest),
+ if
+ %% This token no longer exists!
+ Next#token.finish =< Pos ->
+ io:format("(Pos = ~p) Discaring token: ~p~n", [Pos, Next]),
+ rescan_dirty_cont(Scn, W, Pos, tl(Rest));
+ %% We need to carry on if the token is known to be dirty, or
+ %% if we aren't at the same place that it was scanned from
+ %% before
+ Next#token.dirty == true;
+ Next#token.start /= Pos ->
+ rescan_dirty(Scn, W, Pos, Rest);
+ true ->
+ Rest
+ end.
+
+make_token(Pos, {ok, T, Acs, LookAhead}) ->
+ Type = element(1, T),
+ Len = length(Acs),
+ #token{type=Type,
+ start=Pos,
+ finish=Pos+Len,
+ lookahead=LookAhead};
+make_token(Pos, {skip_token, Acs, LookAhead}) ->
+ Len = length(Acs),
+ #token{type=em_skipped,
+ start=Pos,
+ finish=Pos+Len,
+ lookahead=LookAhead}.
+
+make_error_token(Pos) ->
+ #token{type=em_error,
+ start=Pos,
+ finish=Pos+1,
+ lookahead=1}.
+
diff --git a/mods/src/em_scheme.erl b/mods/src/em_scheme.erl
new file mode 100644
index 0000000..fd4bd14
--- /dev/null
+++ b/mods/src/em_scheme.erl
@@ -0,0 +1,184 @@
+%%%----------------------------------------------------------------------
+%%% File : em_scheme.erl
+%%% Author : Luke Gorrie <luke@bluetail.com>
+%%% Purpose : Scheme-mode
+%%% Created : 30 Apr 2001 by Luke Gorrie <luke@bluetail.com>
+%%%----------------------------------------------------------------------
+
+-module(em_scheme).
+-author('luke@bluetail.com').
+
+-include_lib("ermacs/include/edit.hrl").
+-import(edit_lib, [buffer/1]).
+
+-compile(export_all).
+%%-export([Function/Arity, ...]).
+
+-define(keymap, scheme_mode_map).
+
+-record(tok, {column, % Column number
+ line, % Line number
+ read_ahead, % # chars read ahead
+ token % Token returned from leex
+ }).
+
+mod_init() ->
+ catch edit_keymap:delete(?keymap),
+ init_map(),
+ edit_keymap:global_set_key("C-x s", {?MODULE, scheme_mode, []}),
+ edit_var:add_to_list(auto_mode_alist,
+ {"\.scheme$$", {?MODULE, scheme_mode}}),
+ ok.
+
+init_map() ->
+ edit_keymap:new(?keymap),
+ edit_keymap:bind_each(?keymap, bindings()).
+
+bindings() ->
+ [{"C-i", {?MODULE, reindent_cmd, []}}
+ ].
+
+%% test buffer annotation
+ann_trace(S0, Cord, Text, Start, End) ->
+ io:format("trace: ~p at (~p,~p)~n", [Text, Start, End]),
+ {ok, S0}.
+
+scheme_mode(State) ->
+ Mode = #mode{name="Scheme",
+ id=scheme,
+ keymaps=[?keymap]},
+ Buf = buffer(State),
+ Scanner = em_scan:make_scheme_scanner(),
+ edit_buf:add_annotation(Buf, scan, {em_scan, scan_annotation, [Scanner]},
+ no_scan),
+ %%edit_buf:add_annotation(Buf, scheme, {?MODULE, ann_trace, []}, []),
+ edit_buf:set_mode(Buf, Mode),
+ State.
+
+scan_buffer(State) ->
+ B = buffer(State),
+ C = edit_buf:get_cord(B),
+ Walker = cord:walker(C),
+ Scanner = make_scheme_scanner(),
+ case em_scan:edit_scan(Scanner, Walker) of
+ {error, Rsn} ->
+ edit_util:status_msg(State, "Error: ~s",
+ [em_scheme_scan:format_error(Rsn)]);
+ {ok, Toks} ->
+ edit_util:status_msg(State, "Scan: (~p) ~s",
+ [length(Toks), format_tokens(Toks)])
+ end.
+
+make_scheme_scanner() ->
+ em_scan:make_scanner(em_scheme_scan:yystate(),
+ {em_scheme_scan, yystate},
+ {em_scheme_scan, yyaction}).
+
+format_tokens([A,B|T]) ->
+ format_token(A) ++ ", " ++ format_tokens([B|T]);
+format_tokens([A]) ->
+ format_token(A).
+
+format_token({T, C, L}) ->
+ io_lib:format("~p:~p:~p", [T, C, L]).
+
+scan(W) ->
+ em_scan:edit_scan(make_scheme_scanner(), W).
+
+%%%----------------------------------------------------------------------
+%%% Reindent
+
+reindent_cmd(State) ->
+ B = buffer(State),
+ Start = beginning_of_fun_pos(B),
+ End = edit_lib:beginning_of_line_pos(B),
+ Region = edit_buf:get_region_cord(B, Start, End),
+ Walker = cord:walker(Region),
+ {ok, Scan} = scan(Walker),
+ reindent(B, End, calc_indent(munge(Scan))).
+
+munge([A = {_,_,LineA}, B = {_,_,LineB} | T]) when LineA /= LineB ->
+ [strip(A), newline | munge([B|T])];
+munge([H|T]) ->
+ [strip(H) | munge(T)];
+munge([]) ->
+ [newline].
+
+strip({Type, Col, Line}) -> {Type, Col}.
+
+reindent(Buf, Pos, Lvl) ->
+ Pred = fun(C) -> (C /= $ ) and (C /= $\t) end,
+ End = max(Pos, edit_lib:find_char_forward(Buf, Pred, Pos, 1)),
+ edit_buf:replace(Buf, lists:duplicate(Lvl, $ ), Pos, End).
+
+beginning_of_fun_pos(B) ->
+ Point = min(edit_buf:point_max(B) - 1,
+ max(1, edit_lib:beginning_of_line_pos(B) - 1)),
+ Cord = edit_buf:get_cord(B),
+ case cord_regexp:first_match("^\\(", Cord, Point, backward) of
+ nomatch ->
+ 1;
+ {match, Start, End} ->
+ Start
+ end.
+
+%% Calculate the indent level for the line *following* the tokens `Toks'.
+calc_indent(Toks) ->
+ io:format("calc_indent: ~p~n", [Toks]),
+ calc_indent(Toks, 0, []).
+
+%% ( s : (lambda
+%% push; |(|+2
+calc_indent([{'(', OC},{special,SC}|T], Lvl0, S0) ->
+ S1 = [Lvl0|S0],
+ calc_indent(T, OC+2, S1);
+%% ( a:!\n b:!\n
+%% push; |b|
+calc_indent([{'(',OC}, {_,_}, {_,C}|T], Lvl0, S0) ->
+ S1 = [Lvl0|S0],
+ calc_indent(T, C, S1);
+calc_indent([{'(',OC}|T], Lvl0, S0) ->
+ S1 = [Lvl0|S0],
+ calc_indent(T, OC+1, S1);
+calc_indent([{')',CC}|T], Lvl0, S0) ->
+ [Lvl1|S1] = S0,
+ calc_indent(T, Lvl1, S1);
+calc_indent([H|T], Lvl, S) ->
+ calc_indent(T, Lvl, S);
+calc_indent([], Lvl, S) ->
+ Lvl.
+
+%% calc_indent(Tokens, CurrentLevel, State, Stack)
+%% State = normal | special
+%% Stack = [{State, Level}]
+
+
+%% Opening
+
+% calc_indent([{'(',COpen}, {special, CSpecial}|T], Lvl0, S0, Stk0) ->
+% %% opening a special form
+% calc_indent(T, COpen + 2, special, [{S0, Lvl0}|Stk0]);
+% calc_indent([{'(',COpen}|T], Lvl0, S0, Stk0) ->
+% calc_indent(T, COpen+1, normal, [{S0, Lvl0}|Stk0]);
+% calc_indent([{')', _}|T], Lvl0, S, [{SPrev,LvlPrev}|Stk]) ->
+% calc_indent(T, LvlPrev, SPrev, Stk);
+% calc_indent([{')', _}|T], Lvl0, S, []) ->
+% %% Too many )'s - go back to 0
+% calc_indent(T, 0, normal, []);
+% calc_indent([{Symbol, SC}, newline | T], Lvl0, normal, Stk0)
+% when Symbol == atom; Symbol == special ->
+% calc_indent(T, SC, normal0, Stk0);
+% calc_indent([{atom, _}|T], Lvl0, S0, Stk0) ->
+% calc_indent(T, Lvl0, S0, Stk0);
+% calc_indent([{special, _}|T], Lvl0, S0, Stk0) ->
+% calc_indent(T, Lvl0, S0, Stk0);
+% calc_indent([newline|T], Lvl, S, Stk) ->
+% calc_indent(T, Lvl, S, Stk);
+% calc_indent([], Lvl, S, Stk) ->
+% Lvl.
+
+max(X, Y) when X > Y -> X;
+max(X, Y) -> Y.
+
+min(X, Y) when X < Y -> X;
+min(X, Y) -> Y.
diff --git a/mods/src/em_scheme_scan.erl b/mods/src/em_scheme_scan.erl
new file mode 100644
index 0000000..8021791
--- /dev/null
+++ b/mods/src/em_scheme_scan.erl
@@ -0,0 +1,531 @@
+%% THIS IS A PRE-RELEASE OF LEEX - RELEASED ONLY BECAUSE MANY PEOPLE
+%% WANTED IT - THE OFFICIAL RELEASE WILL PROVIDE A DIFFERENT INCOMPATIBLE
+%% AND BETTER INTERFACE - BE WARNED
+%% PLEASE REPORT ALL BUGS TO THE AUTHOR.
+
+-module('em_scheme_scan').
+
+-export([string/1,string/2,token/2,token/3,tokens/2,tokens/3]).
+-export([format_error/1]).
+
+%% luke
+-export([yystate/0, yystate/6, yyaction/4]).
+
+%% User code. This is placed here to allow extra attributes.
+
+format_error({illegal,S}) -> ["illegal characters ",io_lib:write_string(S)];
+format_error({user,S}) -> S.
+
+string(String) -> string(String, 1).
+
+string(String, Line) -> string(String, Line, String, []).
+
+%% string(InChars, Line, TokenChars, Tokens) ->
+%% {ok,Tokens,Line} | {error,ErrorInfo,Line}.
+
+string([], L, [], Ts) -> %No partial tokens!
+ {ok,yyrev(Ts),L};
+string(Ics0, L0, Tcs, Ts) ->
+ case yystate(yystate(), Ics0, L0, 0, reject, 0) of
+ {A,Alen,Ics1,L1} -> %Accepting end state
+ string_cont(Ics1, L1, yyaction(A, Alen, Tcs, L1), Ts);
+ {A,Alen,Ics1,L1,S1} -> %After an accepting state
+ string_cont(Ics1, L1, yyaction(A, Alen, Tcs, L1), Ts);
+ {reject,Alen,Tlen,Ics1,L1,S1} ->
+ {error,{L1,?MODULE,{illegal,yypre(Tcs, Tlen+1)}},L1};
+ {A,Alen,Tlen,Ics1,L1,S1} ->
+ string_cont(yysuf(Tcs, Alen), L1, yyaction(A, Alen, Tcs, L1), Ts)
+ end.
+
+%% string_cont(RestChars, Line, Token, Tokens)
+%% Test for and remove the end token wrapper.
+
+string_cont(Rest, Line, {token,T}, Ts) ->
+ string(Rest, Line, Rest, [T|Ts]);
+string_cont(Rest, Line, {end_token,T}, Ts) ->
+ string(Rest, Line, Rest, [T|Ts]);
+string_cont(Rest, Line, skip_token, Ts) ->
+ string(Rest, Line, Rest, Ts);
+string_cont(Rest, Line, {error,S}, Ts) ->
+ {error,{Line,?MODULE,{user,S}},Line}.
+
+%% token(Continuation, Chars, Line) ->
+%% {more,Continuation} | {done,ReturnVal,RestChars}.
+%% Must be careful when re-entering to append the latest characters to the
+%% after characters in an accept.
+
+token(Cont, Chars) -> token(Cont, Chars, 1).
+
+token([], Chars, Line) ->
+ token(Chars, Line, yystate(), Chars, 0, reject, 0);
+token({Line,State,Tcs,Tlen,Action,Alen}, Chars, _) ->
+ token(Chars, Line, State, Tcs ++ Chars, Tlen, Action, Alen).
+
+%% token(InChars, Line, State, TokenChars, TokenLen, Accept) ->
+%% {more,Continuation} | {done,ReturnVal,RestChars}.
+
+token(Ics0, L0, S0, Tcs, Tlen0, A0, Alen0) ->
+ case yystate(S0, Ics0, L0, Tlen0, A0, Alen0) of
+ {A1,Alen1,Ics1,L1} -> %Accepting end state
+ token_cont(Ics1, L1, yyaction(A1, Alen1, Tcs, L1));
+ {A1,Alen1,[],L1,S1} -> %After an accepting state
+ {more,{L1,S1,Tcs,Alen1,A1,Alen1}};
+ {A1,Alen1,Ics1,L1,S1} ->
+ token_cont(Ics1, L1, yyaction(A1, Alen1, Tcs, L1));
+ {A1,Alen1,Tlen1,[],L1,S1} -> %After a non-accepting state
+ {more,{L1,S1,Tcs,Tlen1,A1,Alen1}};
+ {reject,Alen1,Tlen1,eof,L1,S1} ->
+ {done,{eof,L1},[]};
+ {reject,Alen1,Tlen1,Ics1,L1,S1} ->
+ {done,{error,{L1,?MODULE,{illegal,yypre(Tcs, Tlen1+1)}},L1},Ics1};
+ {A1,Alen1,Tlen1,Ics1,L1,S1} ->
+ token_cont(yysuf(Tcs, Alen1), L1, yyaction(A1, Alen1, Tcs, L1))
+ end.
+
+%% tokens_cont(RestChars, Line, Token)
+%% Test if we have detected the end token, if so return done else continue.
+
+token_cont(Rest, Line, {token,T}) ->
+ {done,{ok,T,Line},Rest};
+token_cont(Rest, Line, {end_token,T}) ->
+ {done,{ok,T,Line},Rest};
+token_cont(Rest, Line, skip_token) ->
+ token(Rest, Line, yystate(), Rest, 0, reject, 0);
+token_cont(Rest, Line, {error,S}) ->
+ {done,{error,{Line,?MODULE,{user,S}},Line},Rest}.
+
+%% tokens(Continuation, Chars, Line) ->
+%% {more,Continuation} | {done,ReturnVal,RestChars}.
+%% Must be careful when re-entering to append the latest characters to the
+%% after characters in an accept.
+
+tokens(Cont, Chars) -> tokens(Cont, Chars, 1).
+
+tokens([], Chars, Line) ->
+ tokens(Chars, Line, yystate(), Chars, 0, [], reject, 0);
+tokens({tokens,Line,State,Tcs,Tlen,Ts,Action,Alen}, Chars, _) ->
+ tokens(Chars, Line, State, Tcs ++ Chars, Tlen, Ts, Action, Alen);
+tokens({skip_tokens,Line,State,Tcs,Tlen,Error,Action,Alen}, Chars, _) ->
+ skip_tokens(Chars, Line, State, Tcs ++ Chars, Tlen, Error, Action, Alen).
+
+%% tokens(InChars, Line, State, TokenChars, TokenLen, Tokens, Accept) ->
+%% {more,Continuation} | {done,ReturnVal,RestChars}.
+
+tokens(Ics0, L0, S0, Tcs, Tlen0, Ts, A0, Alen0) ->
+ case yystate(S0, Ics0, L0, Tlen0, A0, Alen0) of
+ {A1,Alen1,Ics1,L1} -> %Accepting end state
+ tokens_cont(Ics1, L1, yyaction(A1, Alen1, Tcs, L1), Ts);
+ {A1,Alen1,[],L1,S1} -> %After an accepting state
+ {more,{tokens,L1,S1,Tcs,Alen1,Ts,A1,Alen1}};
+ {A1,Alen1,Ics1,L1,S1} ->
+ tokens_cont(Ics1, L1, yyaction(A1, Alen1, Tcs, L1), Ts);
+ {A1,Alen1,Tlen1,[],L1,S1} -> %After a non-accepting state
+ {more,{tokens,L1,S1,Tcs,Tlen1,Ts,A1,Alen1}};
+ {reject,Alen1,Tlen1,eof,L1,S1} ->
+ {done,if Ts == [] -> {eof,L1};
+ true -> {ok,yyrev(Ts),L1} end,[]};
+ {reject,Alen1,Tlen1,Ics1,L1,S1} ->
+ skip_tokens(yysuf(Tcs, Tlen1+1), L1,
+ {L1,?MODULE,{illegal,yypre(Tcs, Tlen1+1)}});
+ {A1,Alen1,Tlen1,Ics1,L1,S1} ->
+ tokens_cont(yysuf(Tcs, Alen1), L1, yyaction(A1, Alen1, Tcs, L1), Ts)
+ end.
+
+%% tokens_cont(RestChars, Line, Token, Tokens)
+%% Test if we have detected the end token, if so return done else continue.
+
+tokens_cont(Rest, Line, {token,T}, Ts) ->
+ tokens(Rest, Line, yystate(), Rest, 0, [T|Ts], reject, 0);
+tokens_cont(Rest, Line, {end_token,T}, Ts) ->
+ {done,{ok,yyrev(Ts, [T]),Line},Rest};
+tokens_cont(Rest, Line, skip_token, Ts) ->
+ tokens(Rest, Line, yystate(), Rest, 0, Ts, reject, 0);
+tokens_cont(Rest, Line, {error,S}, Ts) ->
+ skip_tokens(Rest, Line, {Line,?MODULE,{user,S}}).
+
+%% token_skip(InChars, Line, Error) -> {done,ReturnVal,RestChars}.
+%% Skip tokens until an end token, junk everything and return the error.
+
+%%skip_tokens(Ics, Line, Error) -> {done,{error,Error,Line},Ics}.
+
+skip_tokens(Ics, Line, Error) ->
+ skip_tokens(Ics, Line, yystate(), Ics, 0, Error, reject, 0).
+
+%% skip_tokens(InChars, Line, State, TokenChars, TokenLen, Tokens, Accept) ->
+%% {more,Continuation} | {done,ReturnVal,RestChars}.
+
+skip_tokens(Ics0, L0, S0, Tcs, Tlen0, Error, A0, Alen0) ->
+ case yystate(S0, Ics0, L0, Tlen0, A0, Alen0) of
+ {A1,Alen1,Ics1,L1} -> %Accepting end state
+ skip_cont(Ics1, L1, yyaction(A1, Alen1, Tcs, L1), Error);
+ {A1,Alen1,[],L1,S1} -> %After an accepting state
+ {more,{skip_tokens,L1,S1,Tcs,Alen1,Error,A1,Alen1}};
+ {A1,Alen1,Ics1,L1,S1} ->
+ skip_cont(Ics1, L1, yyaction(A1, Alen1, Tcs, L1), Error);
+ {A1,Alen1,Tlen1,[],L1,S1} -> %After a non-accepting state
+ {more,{skip_tokens,L1,S1,Tcs,Tlen1,Error,A1,Alen1}};
+ {reject,Alen1,Tlen1,eof,L1,S1} ->
+ {done,{error,Error,L1},[]};
+ {reject,Alen1,Tlen1,Ics1,L1,S1} ->
+ skip_tokens(yysuf(Tcs, Tlen1), L1, Error);
+ {A1,Alen1,Tlen1,Ics1,L1,S1} ->
+ skip_cont(yysuf(Tcs, Alen1), L1, yyaction(A1, Alen1, Tcs, L1), Error)
+ end.
+
+%% skip_cont(RestChars, Line, Token, Error)
+%% Test if we have detected the end token, if so return done else continue.
+
+skip_cont(Rest, Line, {token,T}, Error) ->
+ skip_tokens(Rest, Line, yystate(), Rest, 0, Error, reject, 0);
+skip_cont(Rest, Line, {end_token,T}, Error) ->
+ {done,{error,Error,Line},Rest};
+skip_cont(Rest, Line, {error,S}, Error) ->
+ skip_tokens(Rest, Line, yystate(), Rest, 0, Error, reject, 0);
+skip_cont(Rest, Line, skip_token, Error) ->
+ skip_tokens(Rest, Line, yystate(), Rest, 0, Error, reject, 0).
+
+yyrev(L) -> yyrev(L, []).
+
+yyrev([H|T], Acc) -> yyrev(T, [H|Acc]);
+yyrev([], Acc) -> Acc.
+
+yypre([H|T], N) when N > 0 -> [H|yypre(T, N-1)];
+yypre(L, N) -> [].
+
+yysuf([H|T], N) when N > 0 -> yysuf(T, N-1);
+yysuf(L, 0) -> L.
+
+yysplit(L, N) -> yysplit(L, N, []).
+yysplit([H|T], N, Acc) when N > 0 -> yysplit(T, N-1, [H|Acc]);
+yysplit(L, 0, Acc) -> {lists:reverse(Acc), L}.
+
+%% yystate() -> InitialState.
+%% yystate(State, InChars, Line, Token, ) ->
+%% {Action, AcceptLength, RestChars, Line} | Accepting end state
+%% {Action, AcceptLength, RestChars, Line, State} | Accepting state
+%% {Action, AcceptLength, TokLength, RestChars, Line, State} |
+%% {reject, AcceptLength, TokLength, RestChars, Line, State}.
+%% Generated state transition functions.
+
+yystate() -> 15.
+
+yystate(18, [$\v|Ics], Line, Tlen, Action, Alen) ->
+ yystate(17, Ics, Line, Tlen+1, 3, Tlen);
+yystate(18, [$\f|Ics], Line, Tlen, Action, Alen) ->
+ yystate(17, Ics, Line, Tlen+1, 3, Tlen);
+yystate(18, [C|Ics], Line, Tlen, Action, Alen) when C >= $\000, C =< $\t ->
+ yystate(17, Ics, Line, Tlen+1, 3, Tlen);
+yystate(18, [C|Ics], Line, Tlen, Action, Alen) when C >= $\016, C =< $\037 ->
+ yystate(17, Ics, Line, Tlen+1, 3, Tlen);
+yystate(18, [C|Ics], Line, Tlen, Action, Alen) when C >= $!, C =< $' ->
+ yystate(17, Ics, Line, Tlen+1, 3, Tlen);
+yystate(18, [C|Ics], Line, Tlen, Action, Alen) when C >= $*, C =< $ÿ ->
+ yystate(17, Ics, Line, Tlen+1, 3, Tlen);
+yystate(18, Ics, Line, Tlen, Action, Alen) ->
+ {3,Tlen,Ics,Line,18};
+yystate(17, [$\v|Ics], Line, Tlen, Action, Alen) ->
+ yystate(17, Ics, Line, Tlen+1, 5, Tlen);
+yystate(17, [$\f|Ics], Line, Tlen, Action, Alen) ->
+ yystate(17, Ics, Line, Tlen+1, 5, Tlen);
+yystate(17, [C|Ics], Line, Tlen, Action, Alen) when C >= $\000, C =< $\t ->
+ yystate(17, Ics, Line, Tlen+1, 5, Tlen);
+yystate(17, [C|Ics], Line, Tlen, Action, Alen) when C >= $\016, C =< $\037 ->
+ yystate(17, Ics, Line, Tlen+1, 5, Tlen);
+yystate(17, [C|Ics], Line, Tlen, Action, Alen) when C >= $!, C =< $' ->
+ yystate(17, Ics, Line, Tlen+1, 5, Tlen);
+yystate(17, [C|Ics], Line, Tlen, Action, Alen) when C >= $*, C =< $ÿ ->
+ yystate(17, Ics, Line, Tlen+1, 5, Tlen);
+yystate(17, Ics, Line, Tlen, Action, Alen) ->
+ {5,Tlen,Ics,Line,17};
+yystate(16, [$\v|Ics], Line, Tlen, Action, Alen) ->
+ yystate(17, Ics, Line, Tlen+1, 5, Tlen);
+yystate(16, [$\f|Ics], Line, Tlen, Action, Alen) ->
+ yystate(17, Ics, Line, Tlen+1, 5, Tlen);
+yystate(16, [$e|Ics], Line, Tlen, Action, Alen) ->
+ yystate(18, Ics, Line, Tlen+1, 5, Tlen);
+yystate(16, [C|Ics], Line, Tlen, Action, Alen) when C >= $\000, C =< $\t ->
+ yystate(17, Ics, Line, Tlen+1, 5, Tlen);
+yystate(16, [C|Ics], Line, Tlen, Action, Alen) when C >= $\016, C =< $\037 ->
+ yystate(17, Ics, Line, Tlen+1, 5, Tlen);
+yystate(16, [C|Ics], Line, Tlen, Action, Alen) when C >= $!, C =< $' ->
+ yystate(17, Ics, Line, Tlen+1, 5, Tlen);
+yystate(16, [C|Ics], Line, Tlen, Action, Alen) when C >= $*, C =< $d ->
+ yystate(17, Ics, Line, Tlen+1, 5, Tlen);
+yystate(16, [C|Ics], Line, Tlen, Action, Alen) when C >= $f, C =< $ÿ ->
+ yystate(17, Ics, Line, Tlen+1, 5, Tlen);
+yystate(16, Ics, Line, Tlen, Action, Alen) ->
+ {5,Tlen,Ics,Line,16};
+yystate(15, [$\n|Ics], Line, Tlen, Action, Alen) ->
+ yystate(11, Ics, Line+1, Tlen+1, Action, Alen);
+yystate(15, [$\v|Ics], Line, Tlen, Action, Alen) ->
+ yystate(17, Ics, Line, Tlen+1, Action, Alen);
+yystate(15, [$\f|Ics], Line, Tlen, Action, Alen) ->
+ yystate(17, Ics, Line, Tlen+1, Action, Alen);
+yystate(15, [$\r|Ics], Line, Tlen, Action, Alen) ->
+ yystate(11, Ics, Line, Tlen+1, Action, Alen);
+yystate(15, [$\s|Ics], Line, Tlen, Action, Alen) ->
+ yystate(11, Ics, Line, Tlen+1, Action, Alen);
+yystate(15, [$(|Ics], Line, Tlen, Action, Alen) ->
+ yystate(7, Ics, Line, Tlen+1, Action, Alen);
+yystate(15, [$)|Ics], Line, Tlen, Action, Alen) ->
+ yystate(3, Ics, Line, Tlen+1, Action, Alen);
+yystate(15, [$d|Ics], Line, Tlen, Action, Alen) ->
+ yystate(0, Ics, Line, Tlen+1, Action, Alen);
+yystate(15, [$l|Ics], Line, Tlen, Action, Alen) ->
+ yystate(14, Ics, Line, Tlen+1, Action, Alen);
+yystate(15, [C|Ics], Line, Tlen, Action, Alen) when C >= $\000, C =< $\t ->
+ yystate(17, Ics, Line, Tlen+1, Action, Alen);
+yystate(15, [C|Ics], Line, Tlen, Action, Alen) when C >= $\016, C =< $\037 ->
+ yystate(17, Ics, Line, Tlen+1, Action, Alen);
+yystate(15, [C|Ics], Line, Tlen, Action, Alen) when C >= $!, C =< $' ->
+ yystate(17, Ics, Line, Tlen+1, Action, Alen);
+yystate(15, [C|Ics], Line, Tlen, Action, Alen) when C >= $*, C =< $c ->
+ yystate(17, Ics, Line, Tlen+1, Action, Alen);
+yystate(15, [C|Ics], Line, Tlen, Action, Alen) when C >= $e, C =< $k ->
+ yystate(17, Ics, Line, Tlen+1, Action, Alen);
+yystate(15, [C|Ics], Line, Tlen, Action, Alen) when C >= $m, C =< $ÿ ->
+ yystate(17, Ics, Line, Tlen+1, Action, Alen);
+yystate(15, Ics, Line, Tlen, Action, Alen) ->
+ {Action,Alen,Tlen,Ics,Line,15};
+yystate(14, [$\v|Ics], Line, Tlen, Action, Alen) ->
+ yystate(17, Ics, Line, Tlen+1, 5, Tlen);
+yystate(14, [$\f|Ics], Line, Tlen, Action, Alen) ->
+ yystate(17, Ics, Line, Tlen+1, 5, Tlen);
+yystate(14, [$a|Ics], Line, Tlen, Action, Alen) ->
+ yystate(10, Ics, Line, Tlen+1, 5, Tlen);
+yystate(14, [$e|Ics], Line, Tlen, Action, Alen) ->
+ yystate(9, Ics, Line, Tlen+1, 5, Tlen);
+yystate(14, [C|Ics], Line, Tlen, Action, Alen) when C >= $\000, C =< $\t ->
+ yystate(17, Ics, Line, Tlen+1, 5, Tlen);
+yystate(14, [C|Ics], Line, Tlen, Action, Alen) when C >= $\016, C =< $\037 ->
+ yystate(17, Ics, Line, Tlen+1, 5, Tlen);
+yystate(14, [C|Ics], Line, Tlen, Action, Alen) when C >= $!, C =< $' ->
+ yystate(17, Ics, Line, Tlen+1, 5, Tlen);
+yystate(14, [C|Ics], Line, Tlen, Action, Alen) when C >= $*, C =< $` ->
+ yystate(17, Ics, Line, Tlen+1, 5, Tlen);
+yystate(14, [C|Ics], Line, Tlen, Action, Alen) when C >= $b, C =< $d ->
+ yystate(17, Ics, Line, Tlen+1, 5, Tlen);
+yystate(14, [C|Ics], Line, Tlen, Action, Alen) when C >= $f, C =< $ÿ ->
+ yystate(17, Ics, Line, Tlen+1, 5, Tlen);
+yystate(14, Ics, Line, Tlen, Action, Alen) ->
+ {5,Tlen,Ics,Line,14};
+yystate(13, [$\v|Ics], Line, Tlen, Action, Alen) ->
+ yystate(17, Ics, Line, Tlen+1, 4, Tlen);
+yystate(13, [$\f|Ics], Line, Tlen, Action, Alen) ->
+ yystate(17, Ics, Line, Tlen+1, 4, Tlen);
+yystate(13, [C|Ics], Line, Tlen, Action, Alen) when C >= $\000, C =< $\t ->
+ yystate(17, Ics, Line, Tlen+1, 4, Tlen);
+yystate(13, [C|Ics], Line, Tlen, Action, Alen) when C >= $\016, C =< $\037 ->
+ yystate(17, Ics, Line, Tlen+1, 4, Tlen);
+yystate(13, [C|Ics], Line, Tlen, Action, Alen) when C >= $!, C =< $' ->
+ yystate(17, Ics, Line, Tlen+1, 4, Tlen);
+yystate(13, [C|Ics], Line, Tlen, Action, Alen) when C >= $*, C =< $ÿ ->
+ yystate(17, Ics, Line, Tlen+1, 4, Tlen);
+yystate(13, Ics, Line, Tlen, Action, Alen) ->
+ {4,Tlen,Ics,Line,13};
+yystate(12, [$\v|Ics], Line, Tlen, Action, Alen) ->
+ yystate(17, Ics, Line, Tlen+1, 5, Tlen);
+yystate(12, [$\f|Ics], Line, Tlen, Action, Alen) ->
+ yystate(17, Ics, Line, Tlen+1, 5, Tlen);
+yystate(12, [$n|Ics], Line, Tlen, Action, Alen) ->
+ yystate(16, Ics, Line, Tlen+1, 5, Tlen);
+yystate(12, [C|Ics], Line, Tlen, Action, Alen) when C >= $\000, C =< $\t ->
+ yystate(17, Ics, Line, Tlen+1, 5, Tlen);
+yystate(12, [C|Ics], Line, Tlen, Action, Alen) when C >= $\016, C =< $\037 ->
+ yystate(17, Ics, Line, Tlen+1, 5, Tlen);
+yystate(12, [C|Ics], Line, Tlen, Action, Alen) when C >= $!, C =< $' ->
+ yystate(17, Ics, Line, Tlen+1, 5, Tlen);
+yystate(12, [C|Ics], Line, Tlen, Action, Alen) when C >= $*, C =< $m ->
+ yystate(17, Ics, Line, Tlen+1, 5, Tlen);
+yystate(12, [C|Ics], Line, Tlen, Action, Alen) when C >= $o, C =< $ÿ ->
+ yystate(17, Ics, Line, Tlen+1, 5, Tlen);
+yystate(12, Ics, Line, Tlen, Action, Alen) ->
+ {5,Tlen,Ics,Line,12};
+yystate(11, Ics, Line, Tlen, Action, Alen) ->
+ {6,Tlen,Ics,Line};
+yystate(10, [$\v|Ics], Line, Tlen, Action, Alen) ->
+ yystate(17, Ics, Line, Tlen+1, 5, Tlen);
+yystate(10, [$\f|Ics], Line, Tlen, Action, Alen) ->
+ yystate(17, Ics, Line, Tlen+1, 5, Tlen);
+yystate(10, [$m|Ics], Line, Tlen, Action, Alen) ->
+ yystate(6, Ics, Line, Tlen+1, 5, Tlen);
+yystate(10, [C|Ics], Line, Tlen, Action, Alen) when C >= $\000, C =< $\t ->
+ yystate(17, Ics, Line, Tlen+1, 5, Tlen);
+yystate(10, [C|Ics], Line, Tlen, Action, Alen) when C >= $\016, C =< $\037 ->
+ yystate(17, Ics, Line, Tlen+1, 5, Tlen);
+yystate(10, [C|Ics], Line, Tlen, Action, Alen) when C >= $!, C =< $' ->
+ yystate(17, Ics, Line, Tlen+1, 5, Tlen);
+yystate(10, [C|Ics], Line, Tlen, Action, Alen) when C >= $*, C =< $l ->
+ yystate(17, Ics, Line, Tlen+1, 5, Tlen);
+yystate(10, [C|Ics], Line, Tlen, Action, Alen) when C >= $n, C =< $ÿ ->
+ yystate(17, Ics, Line, Tlen+1, 5, Tlen);
+yystate(10, Ics, Line, Tlen, Action, Alen) ->
+ {5,Tlen,Ics,Line,10};
+yystate(9, [$\v|Ics], Line, Tlen, Action, Alen) ->
+ yystate(17, Ics, Line, Tlen+1, 5, Tlen);
+yystate(9, [$\f|Ics], Line, Tlen, Action, Alen) ->
+ yystate(17, Ics, Line, Tlen+1, 5, Tlen);
+yystate(9, [$t|Ics], Line, Tlen, Action, Alen) ->
+ yystate(13, Ics, Line, Tlen+1, 5, Tlen);
+yystate(9, [C|Ics], Line, Tlen, Action, Alen) when C >= $\000, C =< $\t ->
+ yystate(17, Ics, Line, Tlen+1, 5, Tlen);
+yystate(9, [C|Ics], Line, Tlen, Action, Alen) when C >= $\016, C =< $\037 ->
+ yystate(17, Ics, Line, Tlen+1, 5, Tlen);
+yystate(9, [C|Ics], Line, Tlen, Action, Alen) when C >= $!, C =< $' ->
+ yystate(17, Ics, Line, Tlen+1, 5, Tlen);
+yystate(9, [C|Ics], Line, Tlen, Action, Alen) when C >= $*, C =< $s ->
+ yystate(17, Ics, Line, Tlen+1, 5, Tlen);
+yystate(9, [C|Ics], Line, Tlen, Action, Alen) when C >= $u, C =< $ÿ ->
+ yystate(17, Ics, Line, Tlen+1, 5, Tlen);
+yystate(9, Ics, Line, Tlen, Action, Alen) ->
+ {5,Tlen,Ics,Line,9};
+yystate(8, [$\v|Ics], Line, Tlen, Action, Alen) ->
+ yystate(17, Ics, Line, Tlen+1, 5, Tlen);
+yystate(8, [$\f|Ics], Line, Tlen, Action, Alen) ->
+ yystate(17, Ics, Line, Tlen+1, 5, Tlen);
+yystate(8, [$i|Ics], Line, Tlen, Action, Alen) ->
+ yystate(12, Ics, Line, Tlen+1, 5, Tlen);
+yystate(8, [C|Ics], Line, Tlen, Action, Alen) when C >= $\000, C =< $\t ->
+ yystate(17, Ics, Line, Tlen+1, 5, Tlen);
+yystate(8, [C|Ics], Line, Tlen, Action, Alen) when C >= $\016, C =< $\037 ->
+ yystate(17, Ics, Line, Tlen+1, 5, Tlen);
+yystate(8, [C|Ics], Line, Tlen, Action, Alen) when C >= $!, C =< $' ->
+ yystate(17, Ics, Line, Tlen+1, 5, Tlen);
+yystate(8, [C|Ics], Line, Tlen, Action, Alen) when C >= $*, C =< $h ->
+ yystate(17, Ics, Line, Tlen+1, 5, Tlen);
+yystate(8, [C|Ics], Line, Tlen, Action, Alen) when C >= $j, C =< $ÿ ->
+ yystate(17, Ics, Line, Tlen+1, 5, Tlen);
+yystate(8, Ics, Line, Tlen, Action, Alen) ->
+ {5,Tlen,Ics,Line,8};
+yystate(7, Ics, Line, Tlen, Action, Alen) ->
+ {0,Tlen,Ics,Line};
+yystate(6, [$\v|Ics], Line, Tlen, Action, Alen) ->
+ yystate(17, Ics, Line, Tlen+1, 5, Tlen);
+yystate(6, [$\f|Ics], Line, Tlen, Action, Alen) ->
+ yystate(17, Ics, Line, Tlen+1, 5, Tlen);
+yystate(6, [$b|Ics], Line, Tlen, Action, Alen) ->
+ yystate(2, Ics, Line, Tlen+1, 5, Tlen);
+yystate(6, [C|Ics], Line, Tlen, Action, Alen) when C >= $\000, C =< $\t ->
+ yystate(17, Ics, Line, Tlen+1, 5, Tlen);
+yystate(6, [C|Ics], Line, Tlen, Action, Alen) when C >= $\016, C =< $\037 ->
+ yystate(17, Ics, Line, Tlen+1, 5, Tlen);
+yystate(6, [C|Ics], Line, Tlen, Action, Alen) when C >= $!, C =< $' ->
+ yystate(17, Ics, Line, Tlen+1, 5, Tlen);
+yystate(6, [C|Ics], Line, Tlen, Action, Alen) when C >= $*, C =< $a ->
+ yystate(17, Ics, Line, Tlen+1, 5, Tlen);
+yystate(6, [C|Ics], Line, Tlen, Action, Alen) when C >= $c, C =< $ÿ ->
+ yystate(17, Ics, Line, Tlen+1, 5, Tlen);
+yystate(6, Ics, Line, Tlen, Action, Alen) ->
+ {5,Tlen,Ics,Line,6};
+yystate(5, [$\v|Ics], Line, Tlen, Action, Alen) ->
+ yystate(17, Ics, Line, Tlen+1, 2, Tlen);
+yystate(5, [$\f|Ics], Line, Tlen, Action, Alen) ->
+ yystate(17, Ics, Line, Tlen+1, 2, Tlen);
+yystate(5, [C|Ics], Line, Tlen, Action, Alen) when C >= $\000, C =< $\t ->
+ yystate(17, Ics, Line, Tlen+1, 2, Tlen);
+yystate(5, [C|Ics], Line, Tlen, Action, Alen) when C >= $\016, C =< $\037 ->
+ yystate(17, Ics, Line, Tlen+1, 2, Tlen);
+yystate(5, [C|Ics], Line, Tlen, Action, Alen) when C >= $!, C =< $' ->
+ yystate(17, Ics, Line, Tlen+1, 2, Tlen);
+yystate(5, [C|Ics], Line, Tlen, Action, Alen) when C >= $*, C =< $ÿ ->
+ yystate(17, Ics, Line, Tlen+1, 2, Tlen);
+yystate(5, Ics, Line, Tlen, Action, Alen) ->
+ {2,Tlen,Ics,Line,5};
+yystate(4, [$\v|Ics], Line, Tlen, Action, Alen) ->
+ yystate(17, Ics, Line, Tlen+1, 5, Tlen);
+yystate(4, [$\f|Ics], Line, Tlen, Action, Alen) ->
+ yystate(17, Ics, Line, Tlen+1, 5, Tlen);
+yystate(4, [$f|Ics], Line, Tlen, Action, Alen) ->
+ yystate(8, Ics, Line, Tlen+1, 5, Tlen);
+yystate(4, [C|Ics], Line, Tlen, Action, Alen) when C >= $\000, C =< $\t ->
+ yystate(17, Ics, Line, Tlen+1, 5, Tlen);
+yystate(4, [C|Ics], Line, Tlen, Action, Alen) when C >= $\016, C =< $\037 ->
+ yystate(17, Ics, Line, Tlen+1, 5, Tlen);
+yystate(4, [C|Ics], Line, Tlen, Action, Alen) when C >= $!, C =< $' ->
+ yystate(17, Ics, Line, Tlen+1, 5, Tlen);
+yystate(4, [C|Ics], Line, Tlen, Action, Alen) when C >= $*, C =< $e ->
+ yystate(17, Ics, Line, Tlen+1, 5, Tlen);
+yystate(4, [C|Ics], Line, Tlen, Action, Alen) when C >= $g, C =< $ÿ ->
+ yystate(17, Ics, Line, Tlen+1, 5, Tlen);
+yystate(4, Ics, Line, Tlen, Action, Alen) ->
+ {5,Tlen,Ics,Line,4};
+yystate(3, Ics, Line, Tlen, Action, Alen) ->
+ {1,Tlen,Ics,Line};
+yystate(2, [$\v|Ics], Line, Tlen, Action, Alen) ->
+ yystate(17, Ics, Line, Tlen+1, 5, Tlen);
+yystate(2, [$\f|Ics], Line, Tlen, Action, Alen) ->
+ yystate(17, Ics, Line, Tlen+1, 5, Tlen);
+yystate(2, [$d|Ics], Line, Tlen, Action, Alen) ->
+ yystate(1, Ics, Line, Tlen+1, 5, Tlen);
+yystate(2, [C|Ics], Line, Tlen, Action, Alen) when C >= $\000, C =< $\t ->
+ yystate(17, Ics, Line, Tlen+1, 5, Tlen);
+yystate(2, [C|Ics], Line, Tlen, Action, Alen) when C >= $\016, C =< $\037 ->
+ yystate(17, Ics, Line, Tlen+1, 5, Tlen);
+yystate(2, [C|Ics], Line, Tlen, Action, Alen) when C >= $!, C =< $' ->
+ yystate(17, Ics, Line, Tlen+1, 5, Tlen);
+yystate(2, [C|Ics], Line, Tlen, Action, Alen) when C >= $*, C =< $c ->
+ yystate(17, Ics, Line, Tlen+1, 5, Tlen);
+yystate(2, [C|Ics], Line, Tlen, Action, Alen) when C >= $e, C =< $ÿ ->
+ yystate(17, Ics, Line, Tlen+1, 5, Tlen);
+yystate(2, Ics, Line, Tlen, Action, Alen) ->
+ {5,Tlen,Ics,Line,2};
+yystate(1, [$\v|Ics], Line, Tlen, Action, Alen) ->
+ yystate(17, Ics, Line, Tlen+1, 5, Tlen);
+yystate(1, [$\f|Ics], Line, Tlen, Action, Alen) ->
+ yystate(17, Ics, Line, Tlen+1, 5, Tlen);
+yystate(1, [$a|Ics], Line, Tlen, Action, Alen) ->
+ yystate(5, Ics, Line, Tlen+1, 5, Tlen);
+yystate(1, [C|Ics], Line, Tlen, Action, Alen) when C >= $\000, C =< $\t ->
+ yystate(17, Ics, Line, Tlen+1, 5, Tlen);
+yystate(1, [C|Ics], Line, Tlen, Action, Alen) when C >= $\016, C =< $\037 ->
+ yystate(17, Ics, Line, Tlen+1, 5, Tlen);
+yystate(1, [C|Ics], Line, Tlen, Action, Alen) when C >= $!, C =< $' ->
+ yystate(17, Ics, Line, Tlen+1, 5, Tlen);
+yystate(1, [C|Ics], Line, Tlen, Action, Alen) when C >= $*, C =< $` ->
+ yystate(17, Ics, Line, Tlen+1, 5, Tlen);
+yystate(1, [C|Ics], Line, Tlen, Action, Alen) when C >= $b, C =< $ÿ ->
+ yystate(17, Ics, Line, Tlen+1, 5, Tlen);
+yystate(1, Ics, Line, Tlen, Action, Alen) ->
+ {5,Tlen,Ics,Line,1};
+yystate(0, [$\v|Ics], Line, Tlen, Action, Alen) ->
+ yystate(17, Ics, Line, Tlen+1, 5, Tlen);
+yystate(0, [$\f|Ics], Line, Tlen, Action, Alen) ->
+ yystate(17, Ics, Line, Tlen+1, 5, Tlen);
+yystate(0, [$e|Ics], Line, Tlen, Action, Alen) ->
+ yystate(4, Ics, Line, Tlen+1, 5, Tlen);
+yystate(0, [C|Ics], Line, Tlen, Action, Alen) when C >= $\000, C =< $\t ->
+ yystate(17, Ics, Line, Tlen+1, 5, Tlen);
+yystate(0, [C|Ics], Line, Tlen, Action, Alen) when C >= $\016, C =< $\037 ->
+ yystate(17, Ics, Line, Tlen+1, 5, Tlen);
+yystate(0, [C|Ics], Line, Tlen, Action, Alen) when C >= $!, C =< $' ->
+ yystate(17, Ics, Line, Tlen+1, 5, Tlen);
+yystate(0, [C|Ics], Line, Tlen, Action, Alen) when C >= $*, C =< $d ->
+ yystate(17, Ics, Line, Tlen+1, 5, Tlen);
+yystate(0, [C|Ics], Line, Tlen, Action, Alen) when C >= $f, C =< $ÿ ->
+ yystate(17, Ics, Line, Tlen+1, 5, Tlen);
+yystate(0, Ics, Line, Tlen, Action, Alen) ->
+ {5,Tlen,Ics,Line,0};
+yystate(S, Ics, Line, Tlen, Action, Alen) ->
+ {Action,Alen,Tlen,Ics,Line,S}.
+
+
+%% yyaction(Action, TokenLength, TokenChars, Line) ->
+%% {token,Token} | {end_token, Token} | skip_token | {error,String}.
+%% Generated action function.
+
+yyaction(0, YYlen, YYtcs, YYline) ->
+ {token,{'(',YYline}};
+yyaction(1, YYlen, YYtcs, YYline) ->
+ {token,{')',YYline}};
+yyaction(2, YYlen, YYtcs, YYline) ->
+ {token,{special,YYline}};
+yyaction(3, YYlen, YYtcs, YYline) ->
+ {token,{special,YYline}};
+yyaction(4, YYlen, YYtcs, YYline) ->
+ {token,{special,YYline}};
+yyaction(5, YYlen, YYtcs, YYline) ->
+ YYtext = yypre(YYtcs, YYlen),
+ {token,{atom,YYline,YYtext}};
+yyaction(6, YYlen, YYtcs, YYline) ->
+ skip_token;
+yyaction(_, _, _, _) -> error.
diff --git a/mods/src/em_scheme_scan.xrl b/mods/src/em_scheme_scan.xrl
new file mode 100644
index 0000000..632cf13
--- /dev/null
+++ b/mods/src/em_scheme_scan.xrl
@@ -0,0 +1,18 @@
+Definitions.
+
+AtomChar = [^\s\r\n\(\)]
+WS = [\s\r\n]
+
+Rules.
+
+\( : {token, {'(', YYline}}.
+\) : {token, {')', YYline}}.
+
+lambda : {token, {special, YYline}}.
+define : {token, {special, YYline}}.
+let : {token, {special, YYline}}.
+
+({AtomChar}{AtomChar}*) : {token, {atom, YYline, YYtext}}.
+%% Ignore
+{WS} : skip_token.
+
diff --git a/mods/src/em_stdlib.erl b/mods/src/em_stdlib.erl
new file mode 100644
index 0000000..1bc4687
--- /dev/null
+++ b/mods/src/em_stdlib.erl
@@ -0,0 +1,21 @@
+%%%----------------------------------------------------------------------
+%%% File : em_stdlib.erl
+%%% Author : Luke Gorrie <luke@bluetail.com>
+%%% Purpose : Module for loading the standard library of editor commands.
+%%% This module is loaded/initialised on editor startup.
+%%% Created : 29 Apr 2001 by Luke Gorrie <luke@bluetail.com>
+%%%----------------------------------------------------------------------
+
+-module(em_stdlib).
+-author('luke@bluetail.com').
+
+-export([mod_init/0]).
+
+mod_init() ->
+ lists:foreach(fun(Mod) -> edit_mod:require(Mod) end,
+ mods()).
+
+%% List of modules to be initialised at start-up.
+mods() ->
+ [em_erlang, em_scheme].
+
diff --git a/mods/src/em_test_scan.erl b/mods/src/em_test_scan.erl
new file mode 100644
index 0000000..4a39ca3
--- /dev/null
+++ b/mods/src/em_test_scan.erl
@@ -0,0 +1,255 @@
+%% THIS IS A PRE-RELEASE OF LEEX - RELEASED ONLY BECAUSE MANY PEOPLE
+%% WANTED IT - THE OFFICIAL RELEASE WILL PROVIDE A DIFFERENT INCOMPATIBLE
+%% AND BETTER INTERFACE - BE WARNED
+%% PLEASE REPORT ALL BUGS TO THE AUTHOR.
+
+-module('em_test_scan').
+
+-export([string/1,string/2,token/2,token/3,tokens/2,tokens/3]).
+-export([format_error/1]).
+
+%% luke
+-export([yystate/0, yystate/6, yyaction/4]).
+
+%% User code. This is placed here to allow extra attributes.
+
+format_error({illegal,S}) -> ["illegal characters ",io_lib:write_string(S)];
+format_error({user,S}) -> S.
+
+string(String) -> string(String, 1).
+
+string(String, Line) -> string(String, Line, String, []).
+
+%% string(InChars, Line, TokenChars, Tokens) ->
+%% {ok,Tokens,Line} | {error,ErrorInfo,Line}.
+
+string([], L, [], Ts) -> %No partial tokens!
+ {ok,yyrev(Ts),L};
+string(Ics0, L0, Tcs, Ts) ->
+ case yystate(yystate(), Ics0, L0, 0, reject, 0) of
+ {A,Alen,Ics1,L1} -> %Accepting end state
+ string_cont(Ics1, L1, yyaction(A, Alen, Tcs, L1), Ts);
+ {A,Alen,Ics1,L1,S1} -> %After an accepting state
+ string_cont(Ics1, L1, yyaction(A, Alen, Tcs, L1), Ts);
+ {reject,Alen,Tlen,Ics1,L1,S1} ->
+ {error,{L1,?MODULE,{illegal,yypre(Tcs, Tlen+1)}},L1};
+ {A,Alen,Tlen,Ics1,L1,S1} ->
+ string_cont(yysuf(Tcs, Alen), L1, yyaction(A, Alen, Tcs, L1), Ts)
+ end.
+
+%% string_cont(RestChars, Line, Token, Tokens)
+%% Test for and remove the end token wrapper.
+
+string_cont(Rest, Line, {token,T}, Ts) ->
+ string(Rest, Line, Rest, [T|Ts]);
+string_cont(Rest, Line, {end_token,T}, Ts) ->
+ string(Rest, Line, Rest, [T|Ts]);
+string_cont(Rest, Line, skip_token, Ts) ->
+ string(Rest, Line, Rest, Ts);
+string_cont(Rest, Line, {error,S}, Ts) ->
+ {error,{Line,?MODULE,{user,S}},Line}.
+
+%% token(Continuation, Chars, Line) ->
+%% {more,Continuation} | {done,ReturnVal,RestChars}.
+%% Must be careful when re-entering to append the latest characters to the
+%% after characters in an accept.
+
+token(Cont, Chars) -> token(Cont, Chars, 1).
+
+token([], Chars, Line) ->
+ token(Chars, Line, yystate(), Chars, 0, reject, 0);
+token({Line,State,Tcs,Tlen,Action,Alen}, Chars, _) ->
+ token(Chars, Line, State, Tcs ++ Chars, Tlen, Action, Alen).
+
+%% token(InChars, Line, State, TokenChars, TokenLen, Accept) ->
+%% {more,Continuation} | {done,ReturnVal,RestChars}.
+
+token(Ics0, L0, S0, Tcs, Tlen0, A0, Alen0) ->
+ case yystate(S0, Ics0, L0, Tlen0, A0, Alen0) of
+ {A1,Alen1,Ics1,L1} -> %Accepting end state
+ token_cont(Ics1, L1, yyaction(A1, Alen1, Tcs, L1));
+ {A1,Alen1,[],L1,S1} -> %After an accepting state
+ {more,{L1,S1,Tcs,Alen1,A1,Alen1}};
+ {A1,Alen1,Ics1,L1,S1} ->
+ token_cont(Ics1, L1, yyaction(A1, Alen1, Tcs, L1));
+ {A1,Alen1,Tlen1,[],L1,S1} -> %After a non-accepting state
+ {more,{L1,S1,Tcs,Tlen1,A1,Alen1}};
+ {reject,Alen1,Tlen1,eof,L1,S1} ->
+ {done,{eof,L1},[]};
+ {reject,Alen1,Tlen1,Ics1,L1,S1} ->
+ {done,{error,{L1,?MODULE,{illegal,yypre(Tcs, Tlen1+1)}},L1},Ics1};
+ {A1,Alen1,Tlen1,Ics1,L1,S1} ->
+ token_cont(yysuf(Tcs, Alen1), L1, yyaction(A1, Alen1, Tcs, L1))
+ end.
+
+%% tokens_cont(RestChars, Line, Token)
+%% Test if we have detected the end token, if so return done else continue.
+
+token_cont(Rest, Line, {token,T}) ->
+ {done,{ok,T,Line},Rest};
+token_cont(Rest, Line, {end_token,T}) ->
+ {done,{ok,T,Line},Rest};
+token_cont(Rest, Line, skip_token) ->
+ token(Rest, Line, yystate(), Rest, 0, reject, 0);
+token_cont(Rest, Line, {error,S}) ->
+ {done,{error,{Line,?MODULE,{user,S}},Line},Rest}.
+
+%% tokens(Continuation, Chars, Line) ->
+%% {more,Continuation} | {done,ReturnVal,RestChars}.
+%% Must be careful when re-entering to append the latest characters to the
+%% after characters in an accept.
+
+tokens(Cont, Chars) -> tokens(Cont, Chars, 1).
+
+tokens([], Chars, Line) ->
+ tokens(Chars, Line, yystate(), Chars, 0, [], reject, 0);
+tokens({tokens,Line,State,Tcs,Tlen,Ts,Action,Alen}, Chars, _) ->
+ tokens(Chars, Line, State, Tcs ++ Chars, Tlen, Ts, Action, Alen);
+tokens({skip_tokens,Line,State,Tcs,Tlen,Error,Action,Alen}, Chars, _) ->
+ skip_tokens(Chars, Line, State, Tcs ++ Chars, Tlen, Error, Action, Alen).
+
+%% tokens(InChars, Line, State, TokenChars, TokenLen, Tokens, Accept) ->
+%% {more,Continuation} | {done,ReturnVal,RestChars}.
+
+tokens(Ics0, L0, S0, Tcs, Tlen0, Ts, A0, Alen0) ->
+ case yystate(S0, Ics0, L0, Tlen0, A0, Alen0) of
+ {A1,Alen1,Ics1,L1} -> %Accepting end state
+ tokens_cont(Ics1, L1, yyaction(A1, Alen1, Tcs, L1), Ts);
+ {A1,Alen1,[],L1,S1} -> %After an accepting state
+ {more,{tokens,L1,S1,Tcs,Alen1,Ts,A1,Alen1}};
+ {A1,Alen1,Ics1,L1,S1} ->
+ tokens_cont(Ics1, L1, yyaction(A1, Alen1, Tcs, L1), Ts);
+ {A1,Alen1,Tlen1,[],L1,S1} -> %After a non-accepting state
+ {more,{tokens,L1,S1,Tcs,Tlen1,Ts,A1,Alen1}};
+ {reject,Alen1,Tlen1,eof,L1,S1} ->
+ {done,if Ts == [] -> {eof,L1};
+ true -> {ok,yyrev(Ts),L1} end,[]};
+ {reject,Alen1,Tlen1,Ics1,L1,S1} ->
+ skip_tokens(yysuf(Tcs, Tlen1+1), L1,
+ {L1,?MODULE,{illegal,yypre(Tcs, Tlen1+1)}});
+ {A1,Alen1,Tlen1,Ics1,L1,S1} ->
+ tokens_cont(yysuf(Tcs, Alen1), L1, yyaction(A1, Alen1, Tcs, L1), Ts)
+ end.
+
+%% tokens_cont(RestChars, Line, Token, Tokens)
+%% Test if we have detected the end token, if so return done else continue.
+
+tokens_cont(Rest, Line, {token,T}, Ts) ->
+ tokens(Rest, Line, yystate(), Rest, 0, [T|Ts], reject, 0);
+tokens_cont(Rest, Line, {end_token,T}, Ts) ->
+ {done,{ok,yyrev(Ts, [T]),Line},Rest};
+tokens_cont(Rest, Line, skip_token, Ts) ->
+ tokens(Rest, Line, yystate(), Rest, 0, Ts, reject, 0);
+tokens_cont(Rest, Line, {error,S}, Ts) ->
+ skip_tokens(Rest, Line, {Line,?MODULE,{user,S}}).
+
+%% token_skip(InChars, Line, Error) -> {done,ReturnVal,RestChars}.
+%% Skip tokens until an end token, junk everything and return the error.
+
+%%skip_tokens(Ics, Line, Error) -> {done,{error,Error,Line},Ics}.
+
+skip_tokens(Ics, Line, Error) ->
+ skip_tokens(Ics, Line, yystate(), Ics, 0, Error, reject, 0).
+
+%% skip_tokens(InChars, Line, State, TokenChars, TokenLen, Tokens, Accept) ->
+%% {more,Continuation} | {done,ReturnVal,RestChars}.
+
+skip_tokens(Ics0, L0, S0, Tcs, Tlen0, Error, A0, Alen0) ->
+ case yystate(S0, Ics0, L0, Tlen0, A0, Alen0) of
+ {A1,Alen1,Ics1,L1} -> %Accepting end state
+ skip_cont(Ics1, L1, yyaction(A1, Alen1, Tcs, L1), Error);
+ {A1,Alen1,[],L1,S1} -> %After an accepting state
+ {more,{skip_tokens,L1,S1,Tcs,Alen1,Error,A1,Alen1}};
+ {A1,Alen1,Ics1,L1,S1} ->
+ skip_cont(Ics1, L1, yyaction(A1, Alen1, Tcs, L1), Error);
+ {A1,Alen1,Tlen1,[],L1,S1} -> %After a non-accepting state
+ {more,{skip_tokens,L1,S1,Tcs,Tlen1,Error,A1,Alen1}};
+ {reject,Alen1,Tlen1,eof,L1,S1} ->
+ {done,{error,Error,L1},[]};
+ {reject,Alen1,Tlen1,Ics1,L1,S1} ->
+ skip_tokens(yysuf(Tcs, Tlen1), L1, Error);
+ {A1,Alen1,Tlen1,Ics1,L1,S1} ->
+ skip_cont(yysuf(Tcs, Alen1), L1, yyaction(A1, Alen1, Tcs, L1), Error)
+ end.
+
+%% skip_cont(RestChars, Line, Token, Error)
+%% Test if we have detected the end token, if so return done else continue.
+
+skip_cont(Rest, Line, {token,T}, Error) ->
+ skip_tokens(Rest, Line, yystate(), Rest, 0, Error, reject, 0);
+skip_cont(Rest, Line, {end_token,T}, Error) ->
+ {done,{error,Error,Line},Rest};
+skip_cont(Rest, Line, {error,S}, Error) ->
+ skip_tokens(Rest, Line, yystate(), Rest, 0, Error, reject, 0);
+skip_cont(Rest, Line, skip_token, Error) ->
+ skip_tokens(Rest, Line, yystate(), Rest, 0, Error, reject, 0).
+
+yyrev(L) -> yyrev(L, []).
+
+yyrev([H|T], Acc) -> yyrev(T, [H|Acc]);
+yyrev([], Acc) -> Acc.
+
+yypre([H|T], N) when N > 0 -> [H|yypre(T, N-1)];
+yypre(L, N) -> [].
+
+yysuf([H|T], N) when N > 0 -> yysuf(T, N-1);
+yysuf(L, 0) -> L.
+
+yysplit(L, N) -> yysplit(L, N, []).
+yysplit([H|T], N, Acc) when N > 0 -> yysplit(T, N-1, [H|Acc]);
+yysplit(L, 0, Acc) -> {lists:reverse(Acc), L}.
+
+%% yystate() -> InitialState.
+%% yystate(State, InChars, Line, Token, ) ->
+%% {Action, AcceptLength, RestChars, Line} | Accepting end state
+%% {Action, AcceptLength, RestChars, Line, State} | Accepting state
+%% {Action, AcceptLength, TokLength, RestChars, Line, State} |
+%% {reject, AcceptLength, TokLength, RestChars, Line, State}.
+%% Generated state transition functions.
+
+yystate() -> 2.
+
+yystate(5, [$+|Ics], Line, Tlen, Action, Alen) ->
+ yystate(3, Ics, Line, Tlen+1, 0, Tlen);
+yystate(5, Ics, Line, Tlen, Action, Alen) ->
+ {0,Tlen,Ics,Line,5};
+yystate(4, [C|Ics], Line, Tlen, Action, Alen) when C >= $a, C =< $z ->
+ yystate(4, Ics, Line, Tlen+1, 4, Tlen);
+yystate(4, Ics, Line, Tlen, Action, Alen) ->
+ {4,Tlen,Ics,Line,4};
+yystate(3, Ics, Line, Tlen, Action, Alen) ->
+ {1,Tlen,Ics,Line};
+yystate(2, [$\s|Ics], Line, Tlen, Action, Alen) ->
+ yystate(1, Ics, Line, Tlen+1, Action, Alen);
+yystate(2, [$+|Ics], Line, Tlen, Action, Alen) ->
+ yystate(5, Ics, Line, Tlen+1, Action, Alen);
+yystate(2, [$-|Ics], Line, Tlen, Action, Alen) ->
+ yystate(0, Ics, Line, Tlen+1, Action, Alen);
+yystate(2, [C|Ics], Line, Tlen, Action, Alen) when C >= $a, C =< $z ->
+ yystate(4, Ics, Line, Tlen+1, Action, Alen);
+yystate(2, Ics, Line, Tlen, Action, Alen) ->
+ {Action,Alen,Tlen,Ics,Line,2};
+yystate(1, Ics, Line, Tlen, Action, Alen) ->
+ {3,Tlen,Ics,Line};
+yystate(0, Ics, Line, Tlen, Action, Alen) ->
+ {2,Tlen,Ics,Line};
+yystate(S, Ics, Line, Tlen, Action, Alen) ->
+ {Action,Alen,Tlen,Ics,Line,S}.
+
+
+%% yyaction(Action, TokenLength, TokenChars, Line) ->
+%% {token,Token} | {end_token, Token} | skip_token | {error,String}.
+%% Generated action function.
+
+yyaction(0, YYlen, YYtcs, YYline) ->
+ {token,{'+',YYline}};
+yyaction(1, YYlen, YYtcs, YYline) ->
+ {token,{'++',YYline}};
+yyaction(2, YYlen, YYtcs, YYline) ->
+ {token,{'-',YYline}};
+yyaction(3, YYlen, YYtcs, YYline) ->
+ skip_token;
+yyaction(4, YYlen, YYtcs, YYline) ->
+ YYtext = yypre(YYtcs, YYlen),
+ {token,{atom,YYline,YYtext}};
+yyaction(_, _, _, _) -> error.
diff --git a/mods/src/em_test_scan.xrl b/mods/src/em_test_scan.xrl
new file mode 100644
index 0000000..05ac6bb
--- /dev/null
+++ b/mods/src/em_test_scan.xrl
@@ -0,0 +1,12 @@
+Definitions.
+
+Ch = [a-z]
+
+Rules.
+
+\+ : {token, {'+', YYline}}.
+\+\+ : {token, {'++', YYline}}.
+- : {token, {'-', YYline}}.
+\s : skip_token.
+({Ch}{Ch}*) : {token, {atom, YYline, YYtext}}.
+
diff --git a/mods/src/leex.hrl b/mods/src/leex.hrl
new file mode 100644
index 0000000..4845418
--- /dev/null
+++ b/mods/src/leex.hrl
@@ -0,0 +1,217 @@
+%% THIS IS A PRE-RELEASE OF LEEX - RELEASED ONLY BECAUSE MANY PEOPLE
+%% WANTED IT - THE OFFICIAL RELEASE WILL PROVIDE A DIFFERENT INCOMPATIBLE
+%% AND BETTER INTERFACE - BE WARNED
+%% PLEASE REPORT ALL BUGS TO THE AUTHOR.
+
+##module
+
+-export([string/1,string/2,token/2,token/3,tokens/2,tokens/3]).
+-export([format_error/1]).
+
+%% luke
+-export([yystate/0, yystate/6, yyaction/4]).
+
+%% User code. This is placed here to allow extra attributes.
+##code
+
+format_error({illegal,S}) -> ["illegal characters ",io_lib:write_string(S)];
+format_error({user,S}) -> S.
+
+string(String) -> string(String, 1).
+
+string(String, Line) -> string(String, Line, String, []).
+
+%% string(InChars, Line, TokenChars, Tokens) ->
+%% {ok,Tokens,Line} | {error,ErrorInfo,Line}.
+
+string([], L, [], Ts) -> %No partial tokens!
+ {ok,yyrev(Ts),L};
+string(Ics0, L0, Tcs, Ts) ->
+ case yystate(yystate(), Ics0, L0, 0, reject, 0) of
+ {A,Alen,Ics1,L1} -> %Accepting end state
+ string_cont(Ics1, L1, yyaction(A, Alen, Tcs, L1), Ts);
+ {A,Alen,Ics1,L1,S1} -> %After an accepting state
+ string_cont(Ics1, L1, yyaction(A, Alen, Tcs, L1), Ts);
+ {reject,Alen,Tlen,Ics1,L1,S1} ->
+ {error,{L1,?MODULE,{illegal,yypre(Tcs, Tlen+1)}},L1};
+ {A,Alen,Tlen,Ics1,L1,S1} ->
+ string_cont(yysuf(Tcs, Alen), L1, yyaction(A, Alen, Tcs, L1), Ts)
+ end.
+
+%% string_cont(RestChars, Line, Token, Tokens)
+%% Test for and remove the end token wrapper.
+
+string_cont(Rest, Line, {token,T}, Ts) ->
+ string(Rest, Line, Rest, [T|Ts]);
+string_cont(Rest, Line, {end_token,T}, Ts) ->
+ string(Rest, Line, Rest, [T|Ts]);
+string_cont(Rest, Line, skip_token, Ts) ->
+ string(Rest, Line, Rest, Ts);
+string_cont(Rest, Line, {error,S}, Ts) ->
+ {error,{Line,?MODULE,{user,S}},Line}.
+
+%% token(Continuation, Chars, Line) ->
+%% {more,Continuation} | {done,ReturnVal,RestChars}.
+%% Must be careful when re-entering to append the latest characters to the
+%% after characters in an accept.
+
+token(Cont, Chars) -> token(Cont, Chars, 1).
+
+token([], Chars, Line) ->
+ token(Chars, Line, yystate(), Chars, 0, reject, 0);
+token({Line,State,Tcs,Tlen,Action,Alen}, Chars, _) ->
+ token(Chars, Line, State, Tcs ++ Chars, Tlen, Action, Alen).
+
+%% token(InChars, Line, State, TokenChars, TokenLen, Accept) ->
+%% {more,Continuation} | {done,ReturnVal,RestChars}.
+
+token(Ics0, L0, S0, Tcs, Tlen0, A0, Alen0) ->
+ case yystate(S0, Ics0, L0, Tlen0, A0, Alen0) of
+ {A1,Alen1,Ics1,L1} -> %Accepting end state
+ token_cont(Ics1, L1, yyaction(A1, Alen1, Tcs, L1));
+ {A1,Alen1,[],L1,S1} -> %After an accepting state
+ {more,{L1,S1,Tcs,Alen1,A1,Alen1}};
+ {A1,Alen1,Ics1,L1,S1} ->
+ token_cont(Ics1, L1, yyaction(A1, Alen1, Tcs, L1));
+ {A1,Alen1,Tlen1,[],L1,S1} -> %After a non-accepting state
+ {more,{L1,S1,Tcs,Tlen1,A1,Alen1}};
+ {reject,Alen1,Tlen1,eof,L1,S1} ->
+ {done,{eof,L1},[]};
+ {reject,Alen1,Tlen1,Ics1,L1,S1} ->
+ {done,{error,{L1,?MODULE,{illegal,yypre(Tcs, Tlen1+1)}},L1},Ics1};
+ {A1,Alen1,Tlen1,Ics1,L1,S1} ->
+ token_cont(yysuf(Tcs, Alen1), L1, yyaction(A1, Alen1, Tcs, L1))
+ end.
+
+%% tokens_cont(RestChars, Line, Token)
+%% Test if we have detected the end token, if so return done else continue.
+
+token_cont(Rest, Line, {token,T}) ->
+ {done,{ok,T,Line},Rest};
+token_cont(Rest, Line, {end_token,T}) ->
+ {done,{ok,T,Line},Rest};
+token_cont(Rest, Line, skip_token) ->
+ token(Rest, Line, yystate(), Rest, 0, reject, 0);
+token_cont(Rest, Line, {error,S}) ->
+ {done,{error,{Line,?MODULE,{user,S}},Line},Rest}.
+
+%% tokens(Continuation, Chars, Line) ->
+%% {more,Continuation} | {done,ReturnVal,RestChars}.
+%% Must be careful when re-entering to append the latest characters to the
+%% after characters in an accept.
+
+tokens(Cont, Chars) -> tokens(Cont, Chars, 1).
+
+tokens([], Chars, Line) ->
+ tokens(Chars, Line, yystate(), Chars, 0, [], reject, 0);
+tokens({tokens,Line,State,Tcs,Tlen,Ts,Action,Alen}, Chars, _) ->
+ tokens(Chars, Line, State, Tcs ++ Chars, Tlen, Ts, Action, Alen);
+tokens({skip_tokens,Line,State,Tcs,Tlen,Error,Action,Alen}, Chars, _) ->
+ skip_tokens(Chars, Line, State, Tcs ++ Chars, Tlen, Error, Action, Alen).
+
+%% tokens(InChars, Line, State, TokenChars, TokenLen, Tokens, Accept) ->
+%% {more,Continuation} | {done,ReturnVal,RestChars}.
+
+tokens(Ics0, L0, S0, Tcs, Tlen0, Ts, A0, Alen0) ->
+ case yystate(S0, Ics0, L0, Tlen0, A0, Alen0) of
+ {A1,Alen1,Ics1,L1} -> %Accepting end state
+ tokens_cont(Ics1, L1, yyaction(A1, Alen1, Tcs, L1), Ts);
+ {A1,Alen1,[],L1,S1} -> %After an accepting state
+ {more,{tokens,L1,S1,Tcs,Alen1,Ts,A1,Alen1}};
+ {A1,Alen1,Ics1,L1,S1} ->
+ tokens_cont(Ics1, L1, yyaction(A1, Alen1, Tcs, L1), Ts);
+ {A1,Alen1,Tlen1,[],L1,S1} -> %After a non-accepting state
+ {more,{tokens,L1,S1,Tcs,Tlen1,Ts,A1,Alen1}};
+ {reject,Alen1,Tlen1,eof,L1,S1} ->
+ {done,if Ts == [] -> {eof,L1};
+ true -> {ok,yyrev(Ts),L1} end,[]};
+ {reject,Alen1,Tlen1,Ics1,L1,S1} ->
+ skip_tokens(yysuf(Tcs, Tlen1+1), L1,
+ {L1,?MODULE,{illegal,yypre(Tcs, Tlen1+1)}});
+ {A1,Alen1,Tlen1,Ics1,L1,S1} ->
+ tokens_cont(yysuf(Tcs, Alen1), L1, yyaction(A1, Alen1, Tcs, L1), Ts)
+ end.
+
+%% tokens_cont(RestChars, Line, Token, Tokens)
+%% Test if we have detected the end token, if so return done else continue.
+
+tokens_cont(Rest, Line, {token,T}, Ts) ->
+ tokens(Rest, Line, yystate(), Rest, 0, [T|Ts], reject, 0);
+tokens_cont(Rest, Line, {end_token,T}, Ts) ->
+ {done,{ok,yyrev(Ts, [T]),Line},Rest};
+tokens_cont(Rest, Line, skip_token, Ts) ->
+ tokens(Rest, Line, yystate(), Rest, 0, Ts, reject, 0);
+tokens_cont(Rest, Line, {error,S}, Ts) ->
+ skip_tokens(Rest, Line, {Line,?MODULE,{user,S}}).
+
+%% token_skip(InChars, Line, Error) -> {done,ReturnVal,RestChars}.
+%% Skip tokens until an end token, junk everything and return the error.
+
+%%skip_tokens(Ics, Line, Error) -> {done,{error,Error,Line},Ics}.
+
+skip_tokens(Ics, Line, Error) ->
+ skip_tokens(Ics, Line, yystate(), Ics, 0, Error, reject, 0).
+
+%% skip_tokens(InChars, Line, State, TokenChars, TokenLen, Tokens, Accept) ->
+%% {more,Continuation} | {done,ReturnVal,RestChars}.
+
+skip_tokens(Ics0, L0, S0, Tcs, Tlen0, Error, A0, Alen0) ->
+ case yystate(S0, Ics0, L0, Tlen0, A0, Alen0) of
+ {A1,Alen1,Ics1,L1} -> %Accepting end state
+ skip_cont(Ics1, L1, yyaction(A1, Alen1, Tcs, L1), Error);
+ {A1,Alen1,[],L1,S1} -> %After an accepting state
+ {more,{skip_tokens,L1,S1,Tcs,Alen1,Error,A1,Alen1}};
+ {A1,Alen1,Ics1,L1,S1} ->
+ skip_cont(Ics1, L1, yyaction(A1, Alen1, Tcs, L1), Error);
+ {A1,Alen1,Tlen1,[],L1,S1} -> %After a non-accepting state
+ {more,{skip_tokens,L1,S1,Tcs,Tlen1,Error,A1,Alen1}};
+ {reject,Alen1,Tlen1,eof,L1,S1} ->
+ {done,{error,Error,L1},[]};
+ {reject,Alen1,Tlen1,Ics1,L1,S1} ->
+ skip_tokens(yysuf(Tcs, Tlen1), L1, Error);
+ {A1,Alen1,Tlen1,Ics1,L1,S1} ->
+ skip_cont(yysuf(Tcs, Alen1), L1, yyaction(A1, Alen1, Tcs, L1), Error)
+ end.
+
+%% skip_cont(RestChars, Line, Token, Error)
+%% Test if we have detected the end token, if so return done else continue.
+
+skip_cont(Rest, Line, {token,T}, Error) ->
+ skip_tokens(Rest, Line, yystate(), Rest, 0, Error, reject, 0);
+skip_cont(Rest, Line, {end_token,T}, Error) ->
+ {done,{error,Error,Line},Rest};
+skip_cont(Rest, Line, {error,S}, Error) ->
+ skip_tokens(Rest, Line, yystate(), Rest, 0, Error, reject, 0);
+skip_cont(Rest, Line, skip_token, Error) ->
+ skip_tokens(Rest, Line, yystate(), Rest, 0, Error, reject, 0).
+
+yyrev(L) -> yyrev(L, []).
+
+yyrev([H|T], Acc) -> yyrev(T, [H|Acc]);
+yyrev([], Acc) -> Acc.
+
+yypre([H|T], N) when N > 0 -> [H|yypre(T, N-1)];
+yypre(L, N) -> [].
+
+yysuf([H|T], N) when N > 0 -> yysuf(T, N-1);
+yysuf(L, 0) -> L.
+
+yysplit(L, N) -> yysplit(L, N, []).
+yysplit([H|T], N, Acc) when N > 0 -> yysplit(T, N-1, [H|Acc]);
+yysplit(L, 0, Acc) -> {lists:reverse(Acc), L}.
+
+%% yystate() -> InitialState.
+%% yystate(State, InChars, Line, Token, ) ->
+%% {Action, AcceptLength, RestChars, Line} | Accepting end state
+%% {Action, AcceptLength, RestChars, Line, State} | Accepting state
+%% {Action, AcceptLength, TokLength, RestChars, Line, State} |
+%% {reject, AcceptLength, TokLength, RestChars, Line, State}.
+%% Generated state transition functions.
+
+##dfa
+
+%% yyaction(Action, TokenLength, TokenChars, Line) ->
+%% {token,Token} | {end_token, Token} | skip_token | {error,String}.
+%% Generated action function.
+
+##actions