scratch work

This commit is contained in:
Peter Harpending
2026-06-11 18:23:00 -07:00
parent fe380fcdb3
commit 9a6879cc4a
4 changed files with 864 additions and 0 deletions
+178
View File
@@ -0,0 +1,178 @@
% @doc
% helper functions for grabbing collections of tokens
% off the token stream
%
% generally assume no whitespace/comment tokens in
% input stream
-module(sfc_token_chunks).
-export_type([
]).
-export([
barf/2
]).
% $sfc_include is so c() works from sfp eshell
-include("$sfc_include/sfc.hrl").
%------------------------------------------
% Types
%------------------------------------------
-type chunk_shape()
:: block
| block_item
| {block_item, Level :: pos_integer()}
.
% FIXME
-type choke_reason() :: any().
-spec barf(ChunkShape, SigTokens) -> Perhaps
when ChunkShape :: chunk_shape(),
SigTokens :: Tokens,
Perhaps :: {barf, Taken, Rest}
| {choke, Reason},
Taken :: Tokens,
Rest :: Tokens,
Reason :: choke_reason(),
Tokens :: [sfc_token()].
% @doc
% slurp/barf terminology comes from paredit mode in
% emacs
%
% slurp ~= accepting input
% barf ~= separating input
%
% slurp: (foo bar) baz ~> (foo bar baz)
% barf : (foo bar baz) ~> foo (bar baz)
barf(_, []) ->
{barf, [], []};
barf(block, [H = #sfc_token{pos = {_, BlkCol}} | T]) ->
Take =
fun(#sfc_token{pos = {_, TkCol}}) ->
BlkCol =< TkCol
end,
{A, B} = tw(Take, T),
{barf, [H | A], B};
barf(block_item, [H = #sfc_token{pos = {_, BlkCol}} | T]) ->
Take =
fun(#sfc_token{pos = {_, TkCol}}) ->
BlkCol < TkCol
end,
{A, B} = tw(Take, T),
{barf, [H | A], B}.
barf({block_item, Level}, Tokens = [#sfc_token{pos = {_, StartLevel}} | _]) ->
case Level =:= StartLevel of
false -> {barf, [], Tokens};
true -> barf(block_item, Tokens)
end.
barf(_, _) ->
{choke, #sfc_err_nyi{}}.
% takewhile but returns {Taken, Rest}
tw(Pred, List) ->
tw(Pred, [], List).
tw(Pred, Stk, [X | Xs]) ->
case Pred(X) of
true -> tw(Pred, [X | Stk], Xs);
false -> {lists:reverse(Stk), [X | Xs]}
end;
tw(_, Stk, []) ->
{lists:reverse(Stk), []}.
%-spec consume_delist_round(Tokens) -> Result
% when Tokens :: [sfc_token()],
% Result :: {ok, {Delist, NewTokens}}
% | {error, sfc_err()},
% Delist :: Tokens,
% NewTokens :: Tokens.
%
%consume_delist_round(Tokens = [#sfc_token{type = punct, string = "("} | _]) ->
% consume_delist(Tokens);
%consume_delist_round(Tokens) ->
% {ok, {[], Tokens}}.
%
%
%
%-spec consume_delist_square(Tokens) -> Result
% when Tokens :: [sfc_token()],
% Result :: {ok, {Delist, NewTokens}}
% | {error, sfc_err()},
% Delist :: Tokens,
% NewTokens :: Tokens.
%
%consume_delist_square(Tokens = [#sfc_token{type = punct, string = "["} | _]) ->
% consume_delist(Tokens);
%consume_delist_square(Tokens) ->
% {ok, {[], Tokens}}.
%
%
%
%-spec consume_delist_curly(Tokens) -> Result
% when Tokens :: [sfc_token()],
% Result :: {ok, {Delist, NewTokens}}
% | {error, sfc_err()},
% Delist :: Tokens,
% NewTokens :: Tokens.
%
%consume_delist_curly(Tokens = [#sfc_token{type = punct, string = "{"} | _]) ->
% consume_delist(Tokens);
%consume_delist_curly(Tokens) ->
% {ok, {[], Tokens}}.
%
%
%
%-spec consume_delist(Tokens) -> Result
% when Tokens :: [sfc_token()],
% Result :: {ok, {Delist, NewTokens}}
% | {error, sfc_err()},
% Delist :: Tokens,
% NewTokens :: Tokens.
%
%consume_delist([Head | Tail]) ->
% case Head of
% #sfc_token{type = punct, string = OpenStr = "("} ->
% CloseStr = ")",
% delist_verb(1, {OpenStr, CloseStr}, [Head], Tail);
% #sfc_token{type = punct, string = OpenStr = "["} ->
% CloseStr = "]",
% delist_verb(1, {OpenStr, CloseStr}, [Head], Tail);
% #sfc_token{type = punct, string = OpenStr = "{"} ->
% CloseStr = "}",
% delist_verb(1, {OpenStr, CloseStr}, [Head], Tail);
% _ ->
% {ok, {[], [Head | Tail]}}
% end;
%consume_delist([]) ->
% {ok, {[], []}}.
%
%
%% happy path: have a token and we are in the depth of the list
%delist_verb(Depth, {OpenStr, CloseStr}, Stack, [Tok | Rest]) when Depth >= 1 ->
% NewDepth =
% case Tok of
% % open token -> increase depth
% #sfc_token{type = punct, string = Open} when Open =:= OpenStr ->
% Depth + 1;
% % close token -> decrease depth
% #sfc_token{type = punct, string = Close} when Close =:= CloseStr ->
% Depth - 1;
% _ ->
% Depth
% end,
% delist_verb(NewDepth, {OpenStr, CloseStr}, [Tok | Stack], Rest);
%% we've hit end of available input before a close token
%delist_verb(Depth, {OpenStr, _CloseStr}, _Stack, []) when Depth >= 1 ->
% {error, #sfc_err{atom = unclosed_delimiter,
% string = io_lib:format("unclosed open delimiter: ~p", [OpenStr])}};
%% we've popped back out of the list, we're done
%delist_verb(_Depth = 0, {_OpenStr, _CloseStr}, Stack, Tokens) ->
% {ok, {lists:reverse(Stack), Tokens}}.