From 0aede8cc8a4319d62b9e4b3547c2b76f1462c74a Mon Sep 17 00:00:00 2001 From: Robert Virding Date: Sun, 28 Sep 2008 12:53:36 +0200 Subject: [PATCH] Added new modules lfe_boot and lfe_gen, very cool. Also minor fixes. --- README | 15 ++++++ ebin/lfe_boot.beam | Bin 0 -> 592 bytes ebin/lfe_comp.beam | Bin 2828 -> 2836 bytes ebin/lfe_gen.beam | Bin 0 -> 2856 bytes ebin/lfe_io.beam | Bin 6192 -> 6296 bytes src/ChangeLog | 9 ++++ src/lfe_boot.erl | 44 +++++++++++++++++ src/lfe_comp.erl | 8 ++-- src/lfe_gen.erl | 114 +++++++++++++++++++++++++++++++++++++++++++++ src/lfe_io.erl | 20 ++++---- 10 files changed, 198 insertions(+), 12 deletions(-) create mode 100644 ebin/lfe_boot.beam create mode 100644 ebin/lfe_gen.beam create mode 100644 src/lfe_boot.erl create mode 100644 src/lfe_gen.erl diff --git a/README b/README index 0ecf0143..a5c2a643 100644 --- a/README +++ b/README @@ -5,3 +5,18 @@ code. An LFE evaluator and shell is also included. This is the first version with the modified internal core forms and macro intefaces for the new CL inspired style and the older Scheme inspired style. + +Two new modules have been added: + +lfe_boot allows you start Erlang with the LFE shell running and still +have ^G enabled and user_drv running. Use it as follows: + +erl -noshell -noinput -s lfe_boot start + +NOTE order of commands important, must be -noshell -noinput! Add -pa +to find modules if necessary. + +lfe_gen is a trial interface for using LFE for dynamic code +generation. LFE is much easier to generate as an Erkang list than +Erlang forms. This module helps defining and compiling a module. Note, +that while it works, this module is very experimental and may change. diff --git a/ebin/lfe_boot.beam b/ebin/lfe_boot.beam new file mode 100644 index 0000000000000000000000000000000000000000..332fd0bbae8ada4a87c8fccc70d7285d9e983879 GIT binary patch literal 592 zcmZ8f&ubGw6n?XtY=4;I66v9|heZf9g4rsquthLwOlu*nV!ZT}o$OB1O?PL)&TObx zd-5vumWwBico2_03ONWO9{o3Z_u!kQO7+1v?|pB+`DS-!cAq}K2VgweX*CWSN+baA z2w}~~eb(&>p^8$`RLy6SrQI+c-$+E5#jG3gzOYytQ$DykV5)nq4NVa;^k^b%gpNbR z9Ks~FQN9htsqcY#Xam_W$~!>n^)fP>JVRy^zi!^r4aYH|qtX|+4)&9g&g%&C3I=9^ zC?c%?YNK`fkG^mbpRBEjV_Cu5dMWG7JEtZmgcb+4eJ zgdJNwJl&skfv(bJ>d`elV@Z*v0XuH<{xCpz`)J3kz+X{qwVGmjH{U$6(+~9`eX!a^U5+C2{hUrv$%4} z3Ol=U$vF!Lx5RL=8+RhJ18@=D{Qdjm0`95Vg)B=24N>=0cCAo8Q~%U2Lm?)X7?g@7I$SK0bxcCX`pV9 zNRqp<2C-i%orvF>hG$++}!he+Rd*3_m`OUMg$G|buXf}_%Cj&nShp>cW(hItcemgz% zLa*!fynYzjbb67E(F*)tGVuD1o@bITu_yBRnQ<$Wvca8h*ESm>xDzMav6M9vZDqzd18fA9wmK|DCoM z#Xup^UKHNY6*mg4vwmT-@V~l^x9A+`-lQD+I)x-Pu;b4T0xt}oM)x<89sju7d64LL z7YbB-+?3*G6mO&OHmwtD<0i+pPJw!X9uG$o7E`c?fGf4@uv$>FYi@=MT}>L4nNxw$bAEWZt61$h8PzIecDTp%`gfQt|-RGe4#x9nGoD$W0% zp8uErdQKgdEH1VI3dzdCvGW#Z7s@tNC9B+=5?gJ=K}=WW#JR%_Wi7{XcSdpl@&8#W zQQCII;;5Xh440CB8;i*)ef%ojoKIxZ8L69@k|mIw8297Q&0E60u((u87*&=K%4I2e z80XU%?*==hnTQ6rplqI62F_BOPGi4nmEX7<{UIy19s#~5_pusem zvV}_6$~7=q#kLH`l8V6>-Dc-f(uBub(;0x`Jy2XmIxBMy(#f?ky(_tGpkB@)i5$*q zPP*kBj-qu%Tqsx26zyC}*6Hlm(fs)=HvA>8rk5E*3t2V&o*}9Nn;a9>^on2^N9g92 zIB`ce-$&Fdka&a~9E_BFR@^w%4T%l&8yh404<1it2q9q4GO90 zW=>^rL_gKdYotIWA5ewR$QK8KfyjyJ~VXlqJ)Ng3fZR*g8JBJ6HrUQWp>g0C1Q z6g`Dd*ihIKtt{JGrEK$~UCC;d+L01C3gW;S=;j9e^YGs+SsU=*Kt2w=rXmV5$IC_8 z?u3U6k6ZBADp@W(+;1W}mTMO**G0hC^FV&Bo44Umgu|WhPs!I}-sW{@SGss939@o) zXpE*Eg~2EEGQHayko+z14uCtF5z8saB#?;rv$3=w=O)%EtaX6&0vOw0ir4Q#E&;?% z>-Pb&A^WSq*q7F%{{XliuWvxE0dy6Bbzto4(7O60%71|MG#~-uBMw^Al>-(4(o_6w zye3@+AU={*|CoCwUZ)|6mwe4wN9)AyS)cm$`&eI$@7;lnF5N%HDjr0_U=B4Rhe(@2+ zDlGx(AI(Q&?qBG>4UnGV&}_BD9~S?(-wCM}>hsEzU!2tI^=7@!dtcS}8n5^F_Sg3A zeO27M+o&IW{3oW}JxWpm`~C^}(EnoU)nxsXHBZ(#S=(eilQm4{H(A3K#Grmi;4(lp ztN@Du^<#M_3?>8*vG4?mgi|NO^Ke|L0xTDjYA z!SYv;y+QUVe-L*3{_r%~JobVic8|2Ft@YdMTck6>PS1Ooe1MMrxiQ^XZe$y)jTGHU z4*j#>#CxPQPPU8R_D{~}>v1R>{iZy^M^vZZ9u{l(a6AgnnjOD*@2PxaRIEl{oyGmm ha3FWPjmKc}nsP#0*eu51z3ccwJw?(x4~8Lx_Fvr#@GSrU literal 0 HcmV?d00001 diff --git a/ebin/lfe_io.beam b/ebin/lfe_io.beam index 5616d81f0151d3fdfe748f7433712e23399a00fe..d06088d9fdd9efa69eda8cdaab962c8bab6ad2be 100644 GIT binary patch literal 6296 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 literal 6192 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 diff --git a/src/ChangeLog b/src/ChangeLog index afe06b3c..d72ccf58 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,12 @@ +2008-09-28 + + * lfe_gen.erl: Support for dynamic code generation. + + * lfe_boot.erl: Start Erlang with the LFE shell running. + + * lfe_io.erl (print1_bits): Allow printing of some of the bytes in + a bitstring. + 2008-09-27 * lfe_macro.erl (macro): Apply function of course. diff --git a/src/lfe_boot.erl b/src/lfe_boot.erl new file mode 100644 index 00000000..1ab7eea2 --- /dev/null +++ b/src/lfe_boot.erl @@ -0,0 +1,44 @@ +%% Copyright (c) 2008 Robert Virding. All rights reserved. +%% +%% Redistribution and use in source and binary forms, with or without +%% modification, are permitted provided that the following conditions +%% are met: +%% +%% 1. Redistributions of source code must retain the above copyright +%% notice, this list of conditions and the following disclaimer. +%% 2. Redistributions in binary form must reproduce the above copyright +%% notice, this list of conditions and the following disclaimer in the +%% documentation and/or other materials provided with the distribution. +%% +%% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +%% "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +%% LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +%% FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +%% COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +%% INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +%% BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +%% LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +%% CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +%% LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +%% ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +%% POSSIBILITY OF SUCH DAMAGE. + +%%% File : lfe_boot.erl +%%% Author : Robert Virding +%%% Purpose : Lisp Flavoured Erlang boot module. + +%%% This little beauty allows you to start Erlang with the LFE shell +%%% running and still has ^G and user_drv enabled. Use it as follows: +%%% +%%% erl -noshell -noinput -s lfe_boot start +%%% +%%% NOTE order of commands important, must be -noshell -noinput! Add +%%% -pa to find modules if necessary. +%%% +%%% Thanks to Attila Babo for showing me how to do this. + +-module(lfe_boot). + +-export([start/0]). + +start() -> user_drv:start(['tty_sl -c -e',{lfe_shell,start,[]}]). diff --git a/src/lfe_comp.erl b/src/lfe_comp.erl index 43708b9d..e99de7e7 100644 --- a/src/lfe_comp.erl +++ b/src/lfe_comp.erl @@ -125,10 +125,10 @@ do_return(Core, Warns, St) -> forms(Forms) -> forms(Forms, []). %Default options. forms(Forms, Opts) -> case forms(Forms, #comp{}, Opts) of - {ok,Core,_,St} -> - {ok,Bin} = compile:forms(Core, - [from_core,return_errors|St#comp.opts]), - {ok,St#comp.mod,Bin}; + {ok,Core,Ws,St} -> + {ok,_,Bin} = + compile:forms(Core, [from_core,return_errors|St#comp.opts]), + {ok,St#comp.mod,Bin,Ws}; {error,Es,Ws,_} -> {error,Es,Ws} end. diff --git a/src/lfe_gen.erl b/src/lfe_gen.erl new file mode 100644 index 00000000..8abbd7c4 --- /dev/null +++ b/src/lfe_gen.erl @@ -0,0 +1,114 @@ +%% Copyright (c) 2008 Robert Virding. All rights reserved. +%% +%% Redistribution and use in source and binary forms, with or without +%% modification, are permitted provided that the following conditions +%% are met: +%% +%% 1. Redistributions of source code must retain the above copyright +%% notice, this list of conditions and the following disclaimer. +%% 2. Redistributions in binary form must reproduce the above copyright +%% notice, this list of conditions and the following disclaimer in the +%% documentation and/or other materials provided with the distribution. +%% +%% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +%% "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +%% LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +%% FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +%% COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +%% INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +%% BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +%% LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +%% CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +%% LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +%% ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +%% POSSIBILITY OF SUCH DAMAGE. + +%%% File : lfe_gen.erl +%%% Author : Robert Virding +%%% Purpose : Lisp Flavoured Erlang dynamic code generator. + +-module(lfe_gen). + +-export([compile_forms/1]). +-export([new_module/1,add_exports/2,add_imports/2,add_form/2, + print_mod/1,compile_mod/1]). + +-import(lists, [map/2,foldl/3,mapfoldl/3]). +-import(ordsets, [add_element/2]). +-import(orddict, [store/3,find/2]). + +-record(gen, {name,exps=[],imps=[],atts=[],forms=[]}). + +%% compile_forms(Forms) -> {ok,Name,Bin,Warns} | {error,Errors,Warns}. +%% Compile all LFE module forms in one go. + +compile_forms(Fs0) -> + %% Tag forms with a "line number", just use their index. + {Fs1,_} = mapfoldl(fun (F, N) -> {{F,N},N+1} end, 1, Fs0), + case lfe_comp:forms(Fs1, []) of + {ok,Mod,Bin,Ws} -> {ok,Mod,Bin,Ws}; + {error,Es,Ws} -> {error,Es,Ws} + end. + +%% new_module(Name) -> Module. +%% add_exports([{Name,Arity}], Module) -> Module. +%% add_imports({from,Mod,[{Name,Arity}]}, Module) -> Module. +%% add_form(Form, Module) -> Module. +%% print_mod(Module) -> iolist(). +%% compile_mod(Mod) -> {ok,Name,Bin,Warns} | {error,Errors,Warns}. +%% The incremental interface to compiling a module. + +new_module(Name) -> + #gen{name=Name,forms=[]}. + +add_exports(Exps, Mod) -> + Es0 = Mod#gen.exps, + Es1 = foldl(fun ({N,Ar}, Es) when is_atom(N), is_integer(Ar) -> + add_element({N,Ar}, Es) + end, Es0, Exps), + Mod#gen{exps=Es1}. + +add_imports({from,M,Is}, Mod) -> + Imps0 = Mod#gen.imps, + Imps1 = collect_imp(fun ({F,A}, Imps) -> store({F,A}, F, Imps) end, + M, Imps0, Is), + Mod#gen{imps=Imps1}; +add_imports({rename,M,Is}, Mod) -> + Imps0 = Mod#gen.imps, + Imps1 = collect_imp(fun ({{F,A},R}, Imps) -> store({F,A}, R, Imps) end, + M, Imps0, Is), + Mod#gen{imps=Imps1}. + +add_form(Form, Mod) -> + Mod#gen{forms=Mod#gen.forms ++ [Form]}. + +compile_mod(Mod) -> + Fs = [build_def(Mod)|Mod#gen.forms], + compile_forms(Fs). + +print_mod(Mod) -> %Needs fixing + map(fun (F) -> [lfe_io:prettyprint1(F, 0),io_lib:nl()] end, + [build_def(Mod)|Mod#gen.forms]). + +collect_imp(Fun, Mod, Imps, Is) -> + Mimps0 = safe_fetch(Mod, Imps, []), + Mimps1 = foldl(Fun, Mimps0, Is), + store(Mod, Mimps1, Imps). + +build_def(Mod) -> + Exps = map(fun ({N,I}) -> [N,I] end, Mod#gen.exps), + Imps = map(fun ({M,Is}) -> + [rename,M|map(fun ({{L,Ar},R}) -> [[L,Ar],R] end, + Is)] + end, Mod#gen.imps), + [defmodule,Mod#gen.name, + [export|Exps], + [import|Imps]]. + +%% safe_fetch(Key, Dict, Default) -> Value. + +safe_fetch(Key, D, Def) -> + case find(Key, D) of + {ok,Val} -> Val; + error -> Def + end. diff --git a/src/lfe_io.erl b/src/lfe_io.erl index 98733043..23032838 100644 --- a/src/lfe_io.erl +++ b/src/lfe_io.erl @@ -146,11 +146,14 @@ print1_symb(Symb) -> %% Print the bytes in a bitstring. Print bytes except for last which %% we print as bitstring segement if not 8 bits big. -print1_bits(<>) -> integer_to_list(B); %Catch last binary byte -print1_bits(<>) -> - [integer_to_list(B),$\s|print1_bits(Bits)]; -print1_bits(<<>>) -> []; -print1_bits(Bits) -> %0 < Size < 8 +print1_bits(Bits) -> print1_bits(Bits, -1). %Print them all + +print1_bits(_, 0) -> "..."; +print1_bits(<>, _) -> integer_to_list(B); %Catch last binary byte +print1_bits(<>, N) -> + [integer_to_list(B),$\s|print1_bits(Bits, N-1)]; +print1_bits(<<>>, _) -> []; +print1_bits(Bits, _) -> %0 < Size < 8 N = bit_size(Bits), <> = Bits, io_lib:format("(~w bitstring (size ~w))", [B,N]). @@ -288,7 +291,7 @@ prettyprint1(Tup, I) when is_tuple(Tup) -> ["#(",prettyprint1(hd(List), I+2),pp_tail(tl(List), I+2),")"] end; prettyprint1(Bit, _) when is_bitstring(Bit) -> - ["#B(",print1_bits(Bit),$)]. + ["#B(",print1_bits(Bit, 30),$)]. %First 30 bytes %% split(N, List) -> {List1,List2}. %% Split a list into two lists, the first containing the first N @@ -323,8 +326,7 @@ indent_type('let-syntax') -> 1; indent_type('syntax-rules') -> 0; indent_type('macro') -> 0; %% New style functions. -indent_type('define-function') -> 1; -indent_type('define-macro') -> 1; +indent_type('defmodule') -> 1; indent_type('defun') -> 1; indent_type('defmacro') -> 1; indent_type('defsyntax') -> 1; @@ -343,6 +345,8 @@ indent_type('cond') -> 999; %All following forms indent_type('catch') -> 0; indent_type('try') -> 1; indent_type('call') -> 2; +indent_type('define-function') -> 1; +indent_type('define-macro') -> 1; %% Core macros. indent_type('let*') -> 1; indent_type('flet') -> 1;