diff --git a/test/gsc_test_ytree.erl b/test/gsc_test_ytree.erl index 6cbbe52..8c5d9af 100644 --- a/test/gsc_test_ytree.erl +++ b/test/gsc_test_ytree.erl @@ -1,27 +1,101 @@ -module(gsc_test_ytree). --include("$gsc_include/gsc.hrl"). - -export([main/0]). - - -% @doc ys = syntax stem --record(ys, - {tks :: [tk()], - sig :: [tk()], - mta :: any(), - fst :: list(any())}). - -% syntax tree --type yt(StemT, LeafT) :: LeafT - | #ys{mta :: StemT, - fst :: [yt(StemT, LeafT)]}. - -% syntax forest --type yf(StemT, LeafT) :: [yt(StemT, LeafT)]. - +-include("$gsc_include/gsc.hrl"). main() -> Src = "type foo = bar", - io:format("~ts~n", [Src]). + handle_src_str(Src). +-type syntax_target() :: signal + | file + | {block_of, syntax_target()} + | top_decl + | contract + | interface + | namespace + | '@compiler' + | include + | 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()}). + +%% @doc This is all the stuff needed to be consumed before parsin +%% anything in the contract +-type contract_meta() :: #ct{}. + + +%% @doc +%% This is all the stuff that has to be parsed before actual parsing +%% can begin. +-type stem_meta() :: 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{}]}). + +-type syntax_stem() :: #ys{}. + + +handle_src_str(SrcStr) -> + {ok, Sig} = gsc:unsafe_signal_from_string(SrcStr), + gulp(file, Sig); + + +gulp(file, Sig) -> + gulp({block_of, top_decl}, Sig); +gulp({block_of, X}, Sig) -> + {gulp, BlockItems} = gsc_signal:gulp_block_items(Sig), + #ys{target = {block_of, X}, + signal = Sig, + stem_meta = none, + forest = [gulp(X, Item) | Item <- BlockItems]}; +gulp(top_decl, Sig) -> + % TopDecl ::= ['payable'] ['main'] 'contract' Con [Implement] '=' Block(Decl) + % | 'contract' 'interface' Con [Implement] '=' Block(Decl) + % | 'namespace' Con '=' Block(Decl) + % | '@compiler' PragmaOp Version + % | 'include' String + % | Using + NewTarget = + case gsc_tokens:strings(3, Sig) of + ["namespace", _, _] -> namespace; + ["@compiler", _, _] -> '@compiler'; + ["include", _, _] -> include; + ["using", _, _] -> using; + ["payable", "main", "contract"] -> contract; + ["payable", "contract", "interface"] -> interface; + ["payable", "contract", _] -> contract; + ["contract", "interface", _] -> interface; + ["contract", _, _] -> contract; + ["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]; +gulp(NyiTarget, Sig) -> + #ys{target = NyiTarget, + signal = Sig, + stem_meta = {nyi, NyiTarget}, + forest = []}. + + +%% ['payable'] ['main'] 'contract' Con [Implement] '=' Block(Decl) +slurp(M = #ct{payable = undefined}, [#tk{str = "payable"} | Rest]) -> + slurp(M#ct{payable = true}, Rest) ->