%% -*- erlang -*- %% %% cf_client %% %% Copyright 2015-2018 Jörgen Brandt %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. %% You may obtain a copy of the License at %% %% http://www.apache.org/licenses/LICENSE-2.0 %% %% Unless required by applicable law or agreed to in writing, software %% distributed under the License is distributed on an "AS IS" BASIS, %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %% See the License for the specific language governing permissions and %% limitations under the License. %% %% ------------------------------------------------------------------- %% @author Jörgen Brandt %% @version 0.1.6 %% @copyright 2015-2018 Jörgen Brandt %% %% %% %% %% %% @end %% ------------------------------------------------------------------- -module( cuneiform_preproc ). %%==================================================================== %% Exports %%==================================================================== -export( [visit_from/3, visit_fold/7, visit_cnd/6, visit_for/5] ). %%==================================================================== %% Includes %%==================================================================== -include( "cuneiform.hrl" ). %%==================================================================== %% Imports %%==================================================================== -import( cuneiform_lang, [typed_bind/3, create_closure/2, fold/4, cnd/4, for/4] ). %%==================================================================== %% Preprocessor functions %%==================================================================== -spec visit_from( Id, T, E ) -> typed_bind() when Id :: {id, _, S :: string()}, T :: t(), E :: e(). visit_from( {id, _, S}, T, E ) -> typed_bind( list_to_atom( S ), T, E ). -spec visit_fold( Fold, Id, T, E, From, DefLst, EBody ) -> e() when Fold :: {fold, L :: pos_integer(), _}, Id :: {id, _, S :: string()}, T :: t(), E :: e(), From :: typed_bind(), DefLst :: [assign()], EBody :: e(). visit_fold( {fold, L, _}, {id, _, S}, T, E, From, DefLst, EBody ) -> AccBind = typed_bind( list_to_atom( S ), T, E ), case create_closure( DefLst, EBody ) of {ok, C} -> fold( L, AccBind, From, C ); {error, Reason} -> throw( Reason ) end. -spec visit_cnd( Cnd, EIf, DefLstThen, EThen, DefLstElse, EElse ) -> e() when Cnd :: {cnd, L :: pos_integer(), _}, EIf :: e(), DefLstThen :: [assign()], EThen :: e(), DefLstElse :: [assign()], EElse :: e(). visit_cnd( {cnd, L, _}, EIf, DefLstThen, EThen, DefLstElse, EElse ) -> case create_closure( DefLstThen, EThen ) of {error, R2} -> throw( R2 ); {ok, E2} -> case create_closure( DefLstElse, EElse ) of {error, R3} -> throw( R3 ); {ok, E3} -> cnd( L, EIf, E2, E3 ) end end. -spec visit_for( For, FromLst, DefLst, E, TRet ) -> e() when For :: {for, L :: pos_integer(), _}, FromLst :: [typed_bind()], DefLst :: [assign()], E :: e(), TRet :: t(). visit_for( {for, L, _}, FromLst, DefLst, E, TRet ) -> case create_closure( DefLst, E ) of {ok, C} -> for( L, TRet, FromLst, C ); {error, Reason} -> throw( Reason ) end.