From 5b98b60c9822003f1c5a6d28321a0a96e4012cfc Mon Sep 17 00:00:00 2001 From: Nicklas W Bjurman Date: Wed, 2 Jul 2014 11:48:03 +0200 Subject: [PATCH 1/4] Added option to not load module --- src/dynamic_compile.erl | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/src/dynamic_compile.erl b/src/dynamic_compile.erl index fce6e0f..3affd7b 100644 --- a/src/dynamic_compile.erl +++ b/src/dynamic_compile.erl @@ -41,6 +41,7 @@ -module(dynamic_compile). %% API +-export([forms_from_string/1]). -export([load_from_string/1, load_from_string/2]). -export([from_string/1, from_string/2]). @@ -49,6 +50,40 @@ %%==================================================================== %% API %%==================================================================== + +%%-------------------------------------------------------------------- +%% Function: +%% Description: +%% Returns forms which can be used with +%% compile:forms(Forms) +%%-------------------------------------------------------------------- +forms_from_string(CodeStr) -> + forms_from_string(CodeStr, []). + +forms_from_string(CodeStr, CompileFormsOptions) -> + %% Initialise the macro dictionary with the default predefined macros, + %% (adapted from epp.erl:predef_macros/1 + Filename = "compiled_from_string", + %%Machine = list_to_atom(erlang:system_info(machine)), + Ms0 = dict:new(), + % Ms1 = dict:store('FILE', {[], "compiled_from_string"}, Ms0), + % Ms2 = dict:store('LINE', {[], 1}, Ms1), % actually we might add special code for this + % Ms3 = dict:store('MODULE', {[], undefined}, Ms2), + % Ms4 = dict:store('MODULE_STRING', {[], undefined}, Ms3), + % Ms5 = dict:store('MACHINE', {[], Machine}, Ms4), + % InitMD = dict:store(Machine, {[], true}, Ms5), + InitMD = Ms0, + + %% From the docs for compile:forms: + %% When encountering an -include or -include_dir directive, the compiler searches for header files in the following directories: + %% 1. ".", the current working directory of the file server; + %% 2. the base name of the compiled file; + %% 3. the directories specified using the i option. The directory specified last is searched first. + %% In this case, #2 is meaningless. + IncludeSearchPath = ["." | reverse([Dir || {i, Dir} <- CompileFormsOptions])], + {RevForms, _OutMacroDict} = scan_and_parse(CodeStr, Filename, 1, [], InitMD, IncludeSearchPath), + Forms = reverse(RevForms), + %%-------------------------------------------------------------------- %% Function: %% Description: From 2bbdf6c76c801eac45f87dd866d06072ffe0a295 Mon Sep 17 00:00:00 2001 From: Nicklas W Bjurman Date: Wed, 2 Jul 2014 11:49:05 +0200 Subject: [PATCH 2/4] Fixed syntax error --- src/dynamic_compile.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dynamic_compile.erl b/src/dynamic_compile.erl index 3affd7b..d8529ba 100644 --- a/src/dynamic_compile.erl +++ b/src/dynamic_compile.erl @@ -82,7 +82,7 @@ forms_from_string(CodeStr, CompileFormsOptions) -> %% In this case, #2 is meaningless. IncludeSearchPath = ["." | reverse([Dir || {i, Dir} <- CompileFormsOptions])], {RevForms, _OutMacroDict} = scan_and_parse(CodeStr, Filename, 1, [], InitMD, IncludeSearchPath), - Forms = reverse(RevForms), + reverse(RevForms). %%-------------------------------------------------------------------- %% Function: From 256a1baccb7fa79552ce7780236b790aab885bf7 Mon Sep 17 00:00:00 2001 From: Nicklas W Bjurman Date: Wed, 2 Jul 2014 13:00:34 +0200 Subject: [PATCH 3/4] Refactored out get_forms --- src/dynamic_compile.erl | 65 +++++++++++++++++------------------------ 1 file changed, 27 insertions(+), 38 deletions(-) diff --git a/src/dynamic_compile.erl b/src/dynamic_compile.erl index d8529ba..ddf94bd 100644 --- a/src/dynamic_compile.erl +++ b/src/dynamic_compile.erl @@ -60,28 +60,9 @@ forms_from_string(CodeStr) -> forms_from_string(CodeStr, []). +% takes Options as for compile:forms/2 forms_from_string(CodeStr, CompileFormsOptions) -> - %% Initialise the macro dictionary with the default predefined macros, - %% (adapted from epp.erl:predef_macros/1 - Filename = "compiled_from_string", - %%Machine = list_to_atom(erlang:system_info(machine)), - Ms0 = dict:new(), - % Ms1 = dict:store('FILE', {[], "compiled_from_string"}, Ms0), - % Ms2 = dict:store('LINE', {[], 1}, Ms1), % actually we might add special code for this - % Ms3 = dict:store('MODULE', {[], undefined}, Ms2), - % Ms4 = dict:store('MODULE_STRING', {[], undefined}, Ms3), - % Ms5 = dict:store('MACHINE', {[], Machine}, Ms4), - % InitMD = dict:store(Machine, {[], true}, Ms5), - InitMD = Ms0, - - %% From the docs for compile:forms: - %% When encountering an -include or -include_dir directive, the compiler searches for header files in the following directories: - %% 1. ".", the current working directory of the file server; - %% 2. the base name of the compiled file; - %% 3. the directories specified using the i option. The directory specified last is searched first. - %% In this case, #2 is meaningless. - IncludeSearchPath = ["." | reverse([Dir || {i, Dir} <- CompileFormsOptions])], - {RevForms, _OutMacroDict} = scan_and_parse(CodeStr, Filename, 1, [], InitMD, IncludeSearchPath), + {RevForms, _OutMacroDict} = get_forms(CodeStr, CompileFormsOptions), reverse(RevForms). %%-------------------------------------------------------------------- @@ -107,6 +88,30 @@ from_string(CodeStr) -> % takes Options as for compile:forms/2 from_string(CodeStr, CompileFormsOptions) -> + {RevForms, _OutMacroDict} = get_forms(CodeStr, CompileFormsOptions), + Forms = [{attribute, 0, file, {"compiled_from_string", 0}}|reverse([{eof, 0}|RevForms])], + + %% note: 'binary' is forced as an implicit option, whether it is provided or not. + case compile:forms(Forms, CompileFormsOptions) of + {ok, ModuleName, CompiledCodeBinary} when is_binary(CompiledCodeBinary) -> + {ModuleName, CompiledCodeBinary}; + {ok, ModuleName, CompiledCodeBinary, []} when is_binary(CompiledCodeBinary) -> % empty warnings list + {ModuleName, CompiledCodeBinary}; + {ok, _ModuleName, _CompiledCodeBinary, Warnings} -> + throw({?MODULE, warnings, Warnings}); + Other -> + throw({?MODULE, compile_forms, Other}) + end. + +%%==================================================================== +%% Internal functions +%%==================================================================== +%%%## 'get_forms' +%%% +%%% Get forms from string to be used in companion +%%% with other forms for manual compilation. +%% returns {ReverseForms, FinalMacroDict} +get_forms(CodeStr, CompileFormsOptions) -> %% Initialise the macro dictionary with the default predefined macros, %% (adapted from epp.erl:predef_macros/1 Filename = "compiled_from_string", @@ -127,24 +132,8 @@ from_string(CodeStr, CompileFormsOptions) -> %% 3. the directories specified using the i option. The directory specified last is searched first. %% In this case, #2 is meaningless. IncludeSearchPath = ["." | reverse([Dir || {i, Dir} <- CompileFormsOptions])], - {RevForms, _OutMacroDict} = scan_and_parse(CodeStr, Filename, 1, [], InitMD, IncludeSearchPath), - Forms = [{attribute, 0, file, {"compiled_from_string", 0}}|reverse([{eof, 0}|RevForms])], - - %% note: 'binary' is forced as an implicit option, whether it is provided or not. - case compile:forms(Forms, CompileFormsOptions) of - {ok, ModuleName, CompiledCodeBinary} when is_binary(CompiledCodeBinary) -> - {ModuleName, CompiledCodeBinary}; - {ok, ModuleName, CompiledCodeBinary, []} when is_binary(CompiledCodeBinary) -> % empty warnings list - {ModuleName, CompiledCodeBinary}; - {ok, _ModuleName, _CompiledCodeBinary, Warnings} -> - throw({?MODULE, warnings, Warnings}); - Other -> - throw({?MODULE, compile_forms, Other}) - end. + scan_and_parse(CodeStr, Filename, 1, [], InitMD, IncludeSearchPath), -%%==================================================================== -%% Internal functions -%%==================================================================== %%% Code from Mats Cronqvist %%% See http://www.erlang.org/pipermail/erlang-questions/2007-March/025507.html %%%## 'scan_and_parse' From 33a5de9df81ccbbe995ca1ad0a0d1fd839664a48 Mon Sep 17 00:00:00 2001 From: Nicklas W Bjurman Date: Wed, 2 Jul 2014 13:01:51 +0200 Subject: [PATCH 4/4] Fixed syntax error --- src/dynamic_compile.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dynamic_compile.erl b/src/dynamic_compile.erl index ddf94bd..812a5fa 100644 --- a/src/dynamic_compile.erl +++ b/src/dynamic_compile.erl @@ -132,7 +132,7 @@ get_forms(CodeStr, CompileFormsOptions) -> %% 3. the directories specified using the i option. The directory specified last is searched first. %% In this case, #2 is meaningless. IncludeSearchPath = ["." | reverse([Dir || {i, Dir} <- CompileFormsOptions])], - scan_and_parse(CodeStr, Filename, 1, [], InitMD, IncludeSearchPath), + scan_and_parse(CodeStr, Filename, 1, [], InitMD, IncludeSearchPath). %%% Code from Mats Cronqvist %%% See http://www.erlang.org/pipermail/erlang-questions/2007-March/025507.html