[wip] ytree works on its 1 test example
This commit is contained in:
+4
-5
@@ -38,11 +38,10 @@ is_block([#tk{pos = {_, BCol}} | Rest]) ->
|
||||
|
||||
|
||||
-spec gulp_block_items(Signal) -> Result when
|
||||
Signal :: [tk()],
|
||||
Result :: {gulp, Items}
|
||||
| {error, any()},
|
||||
Items :: [Signal],
|
||||
NewSignal :: Signal.
|
||||
Signal :: [tk()],
|
||||
Result :: {gulp, [Item]}
|
||||
| {error, any()},
|
||||
Item :: Signal.
|
||||
|
||||
gulp_block_items(S) ->
|
||||
case is_block(S) of
|
||||
|
||||
+37
-13
@@ -29,7 +29,7 @@
|
||||
take_while/3,
|
||||
take_block/1,
|
||||
take_block_item/1,
|
||||
strings/2,
|
||||
strings/2, strs/2,
|
||||
slurp_plist/1
|
||||
]).
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
very_stable_string/1,
|
||||
very_stable_characters/1,
|
||||
tokens_from_iolist/1,
|
||||
tokens_from_string/1,
|
||||
tokens/1,
|
||||
slurp_token/2,
|
||||
slurp_token_shapes/3,
|
||||
@@ -57,18 +58,32 @@
|
||||
% API: functions
|
||||
%=======================================================
|
||||
|
||||
-spec strings(N, Tokens) -> AtMostNStrings
|
||||
when N :: non_neg_integer(),
|
||||
-spec strs(N, Tokens) -> AtMostNStrings
|
||||
when N :: infinity | non_neg_integer(),
|
||||
Tokens :: [tk()],
|
||||
AtMostNStrings :: [string()].
|
||||
% @doc return the strings of the first N tokens
|
||||
%% @equiv `strings/2'
|
||||
|
||||
strings(N, [#tk{str = S} | Rest]) when is_integer(N), N >= 1 ->
|
||||
[S | strings(N-1, Rest)];
|
||||
strings(_, []) ->
|
||||
[];
|
||||
strings(0, _) ->
|
||||
[].
|
||||
strs(N, Tks) -> strings(N, Tks).
|
||||
|
||||
|
||||
|
||||
-spec strings(N, Tokens) -> AtMostNStrings
|
||||
when N :: infinity | non_neg_integer(),
|
||||
Tokens :: [tk()],
|
||||
AtMostNStrings :: [string()].
|
||||
%% @doc return the strings of the first N tokens
|
||||
|
||||
strings(N, Tks) when is_integer(N) ->
|
||||
strsn(N, Tks);
|
||||
strings(infinity, Tks) ->
|
||||
[Str || #tk{str = Str} <- Tks].
|
||||
|
||||
|
||||
|
||||
strsn(N, [#tk{str = Str} | Rest]) when N >= 1 -> [Str | strsn(N-1, Rest)];
|
||||
strsn(_, []) -> [];
|
||||
strsn(0, _) -> [].
|
||||
|
||||
|
||||
% used by parser
|
||||
@@ -77,8 +92,7 @@ strings(0, _) ->
|
||||
%
|
||||
% BLOCK =
|
||||
% foo
|
||||
% ...
|
||||
% bar
|
||||
% ... bar
|
||||
% ...
|
||||
% baz
|
||||
% ...
|
||||
@@ -362,10 +376,20 @@ very_stable_codepoints(S) ->
|
||||
| {error, gsc_err()},
|
||||
Tokens :: [tk()].
|
||||
|
||||
% @doc alias for tokens/1
|
||||
%% @equiv `tokens/1'
|
||||
tokens_from_iolist(S) -> tokens(S).
|
||||
|
||||
|
||||
-spec tokens_from_string(SrcStr) -> Result when
|
||||
SrcStr :: iolist(),
|
||||
Result :: {ok, Tokens}
|
||||
| {error, gsc_err()},
|
||||
Tokens :: [tk()].
|
||||
|
||||
%% @equiv `tokens/1'
|
||||
tokens_from_string(S) -> tokens(S).
|
||||
|
||||
|
||||
|
||||
|
||||
-spec tokens(SrcStr) -> Result
|
||||
|
||||
+102
-26
@@ -4,7 +4,11 @@
|
||||
-include("$gsc_include/gsc.hrl").
|
||||
|
||||
main() ->
|
||||
Src = "type foo = bar",
|
||||
Src =
|
||||
"""
|
||||
contract Foo =
|
||||
type foo = bar
|
||||
""",
|
||||
handle_src_str(Src).
|
||||
|
||||
-type syntax_target() :: signal
|
||||
@@ -19,16 +23,13 @@ main() ->
|
||||
| using
|
||||
.
|
||||
|
||||
-type tk() :: gsc_token:token().
|
||||
|
||||
|
||||
-record(ct, {ok = ok :: ok | {error, any()},
|
||||
payable = undefined :: undefined | false | true,
|
||||
main = undefined :: undefined | false | true,
|
||||
contract = undefined :: undefined | tk(),
|
||||
con = undefined :: undefined | tk(),
|
||||
':' = undefined :: undefined | false | {':', [tk()]}
|
||||
'=' = undefined :: undefined | tk()}).
|
||||
-record(ct, {ok = ok :: ok | {error, any()},
|
||||
payable = none :: none | false | true,
|
||||
main = none :: none | false | true,
|
||||
contract = none :: none | tk(),
|
||||
con = none :: none | tk(),
|
||||
impls = none :: none | false | {true, [tk()]},
|
||||
'=' = none :: none | tk()}).
|
||||
|
||||
%% @doc This is all the stuff needed to be consumed before parsin
|
||||
%% anything in the contract
|
||||
@@ -38,21 +39,23 @@ main() ->
|
||||
%% @doc
|
||||
%% This is all the stuff that has to be parsed before actual parsing
|
||||
%% can begin.
|
||||
-type stem_meta() :: contract_meta().
|
||||
-type stem_meta() :: none
|
||||
| contract_meta().
|
||||
|
||||
% @doc ys = syntax stem
|
||||
-record(ys, {ok = ok :: ok | {error, any()},
|
||||
target = signal :: syntax_target(),
|
||||
signal = undefined :: undefined | [tk()],
|
||||
stem_meta = undefined :: undefined | any(),
|
||||
forest = undefined :: undefined | [#ys{}]}).
|
||||
-record(ys, {ok = ok :: ok | {error, any()},
|
||||
target = signal :: syntax_target(),
|
||||
signal :: [tk()],
|
||||
stem_meta :: stem_meta(),
|
||||
forest :: [#ys{}]}).
|
||||
|
||||
-type syntax_stem() :: #ys{}.
|
||||
|
||||
|
||||
handle_src_str(SrcStr) ->
|
||||
{ok, Sig} = gsc:unsafe_signal_from_string(SrcStr),
|
||||
gulp(file, Sig);
|
||||
Sig = gsc:unsafe_signal_from_string(SrcStr),
|
||||
Result = gulp(file, Sig),
|
||||
io:format("~tp~n", [Result]).
|
||||
|
||||
|
||||
gulp(file, Sig) ->
|
||||
@@ -62,7 +65,7 @@ gulp({block_of, X}, Sig) ->
|
||||
#ys{target = {block_of, X},
|
||||
signal = Sig,
|
||||
stem_meta = none,
|
||||
forest = [gulp(X, Item) | Item <- BlockItems]};
|
||||
forest = [gulp(X, Item) || Item <- BlockItems]};
|
||||
gulp(top_decl, Sig) ->
|
||||
% TopDecl ::= ['payable'] ['main'] 'contract' Con [Implement] '=' Block(Decl)
|
||||
% | 'contract' 'interface' Con [Implement] '=' Block(Decl)
|
||||
@@ -81,14 +84,18 @@ gulp(top_decl, Sig) ->
|
||||
["payable", "contract", _] -> contract;
|
||||
["contract", "interface", _] -> interface;
|
||||
["contract", _, _] -> contract;
|
||||
["main", "contract", _] -> contract
|
||||
["main", "payable", "contract"] -> contract
|
||||
end
|
||||
["main", "contract", _] -> contract;
|
||||
["main", "payable", "contract"] -> contract
|
||||
end,
|
||||
gulp(NewTarget, Sig);
|
||||
gulp(contract, Sig) ->
|
||||
{slurp, CtMeta, BlockSignal} = slurp(#ct{}, Sig),
|
||||
{gulp, BlockItems} = gsc_signal:gulp_block_items(BlockSignal),
|
||||
Forest = [gulp(decl, Item) || Item <- BlockItems];
|
||||
Forest = [gulp(decl, Item) || Item <- BlockItems],
|
||||
#ys{target = contract,
|
||||
signal = Sig,
|
||||
stem_meta = CtMeta,
|
||||
forest = Forest};
|
||||
gulp(NyiTarget, Sig) ->
|
||||
#ys{target = NyiTarget,
|
||||
signal = Sig,
|
||||
@@ -97,5 +104,74 @@ gulp(NyiTarget, Sig) ->
|
||||
|
||||
|
||||
%% ['payable'] ['main'] 'contract' Con [Implement] '=' Block(Decl)
|
||||
slurp(M = #ct{payable = undefined}, [#tk{str = "payable"} | Rest]) ->
|
||||
slurp(M#ct{payable = true}, Rest) ->
|
||||
slurp(Meta = #ct{payable = none, main = none}, Sig) ->
|
||||
%% nato phonetic alphabet
|
||||
{Pa, Mi, No} =
|
||||
case gsc_tokens:strings(2, Sig) of
|
||||
["payable", "main"] -> {true, true, 2};
|
||||
["main", "payable"] -> {true, true, 2};
|
||||
["payable", _] -> {true, false, 1};
|
||||
["main", _] -> {false, true, 1};
|
||||
_ -> {false, false, 0}
|
||||
end,
|
||||
NewMeta = Meta#ct{payable = Pa, main = Mi},
|
||||
NewSig = take(No, Sig),
|
||||
slurp(NewMeta, NewSig);
|
||||
slurp(M = #ct{contract = none}, Sig) ->
|
||||
case Sig of
|
||||
[Tk = #tk{str = "contract"} | Rest] ->
|
||||
slurp(M#ct{contract = Tk}, Rest);
|
||||
_ ->
|
||||
M#ct{ok = {error, no_keyword_contract}}
|
||||
end;
|
||||
slurp(M = #ct{con = none}, Sig) ->
|
||||
case Sig of
|
||||
[Tk = #tk{shape = con} | Rest] ->
|
||||
slurp(M#ct{con = Tk}, Rest);
|
||||
[Tk = #tk{str = Irregar} | _] ->
|
||||
M#ct{ok = {error, {illegal_contract_name, Irregar}}};
|
||||
[] ->
|
||||
M#ct{ok = {error, no_contract_name}}
|
||||
end;
|
||||
slurp(M = #ct{impls = none}, Sig) ->
|
||||
case Sig of
|
||||
[Tk = #tk{str = ":"} | Rest] ->
|
||||
{slurp, Impls, NewRest} = slurp({sep1, con, ","}, Rest),
|
||||
NewM = M#ct{impls = {true, Impls}},
|
||||
slurp(NewM, NewRest);
|
||||
_ ->
|
||||
slurp(M#ct{impls = false}, Sig)
|
||||
end;
|
||||
slurp(M = #ct{'=' = none}, Sig) ->
|
||||
case Sig of
|
||||
[Tk = #tk{str = "="} | Rest] ->
|
||||
{slurp, M#ct{'=' = Tk}, Rest};
|
||||
_ ->
|
||||
M#ct{ok = {error, no_token_eq}}
|
||||
end;
|
||||
slurp({sep1, TkShape, SepByStr}, Tks) ->
|
||||
case Tks of
|
||||
[Tk = #tk{shape = TkShape} | Rest] ->
|
||||
slurp_sep1_ii([Tk], TkShape, SepByStr, Rest);
|
||||
_ ->
|
||||
{error, irregar}
|
||||
end;
|
||||
slurp(M, Tks) ->
|
||||
{slurp, {nyi, M}, Tks}.
|
||||
|
||||
|
||||
slurp_sep1_ii(Stk, TkShape, SepByStr, Sig) ->
|
||||
case Sig of
|
||||
[#tk{str = SepByStr}, T = #tk{shape = TkShape} | Rest] ->
|
||||
slurp_sep1_ii([T | Stk], TkShape, SepByStr, Rest);
|
||||
_ ->
|
||||
{slurp, lists:reverse(Stk), Sig}
|
||||
end.
|
||||
|
||||
strings(N, Tks) ->
|
||||
gsc_tokens:strings(N, Tks).
|
||||
|
||||
|
||||
take(N, [_ | Rest]) when N >= 1 -> take(N-1, Rest);
|
||||
take(0, List) -> List;
|
||||
take(_, []) -> [].
|
||||
|
||||
Reference in New Issue
Block a user