1
%% ``The contents of this file are subject to the Erlang Public License,
2
%% Version 1.1, (the "License"); you may not use this file except in
3
%% compliance with the License. You should have received a copy of the
4
%% Erlang Public License along with this software. If not, it can be
5
%% retrieved via the world wide web at http://www.erlang.org/.
7
%% Software distributed under the License is distributed on an "AS IS"
8
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
9
%% the License for the specific language governing rights and limitations
12
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
13
%% Portions created by Ericsson are Copyright 2002, Ericsson Utvecklings
14
%% AB. All Rights Reserved.''
20
-export([start/1, interpret/1]).
22
-import(lists, [foldl/3, map/2, member/2, reverse/1]).
25
X0 = map(fun(I) -> binary_to_list(I) end, X),
26
%% io:format("Escript:~p~n",[X0]),
28
%% io:format("File=~s~n",[File]),
29
{Nerrs, Parse, Mode} = parse_file(File),
32
io:format("Script terminated~n"),
37
interpret(File, Parse, Args);
44
File = atom_to_list(AFile),
45
{Nerrs, Parse, Mode} = parse_include_file(File, 0, [], interpret),
49
io:format("Script terminated~n"),
54
interpret(File, Parse, Args);
60
interpret(File, Parse, Args) ->
61
Dict = parse_to_dict(Parse),
62
ArgsA = erl_parse:abstract(Args, 999),
63
Call = {call,999,{atom,999,main},[ArgsA]},
65
erl_eval:new_bindings(),
67
code_handler(I, J, Dict, File)
72
compile(Parse, Args) ->
74
case compile:forms([Mod|Parse]) of
75
{ok, Module, BeamCode} ->
76
erlang:load_module(Module, BeamCode),
77
apply(Module, main, [Args]),
80
io:format("Compiler errors~n"),
85
parse_to_dict(L) -> parse_to_dict(L, dict:new()).
87
parse_to_dict([{function,_,Name,Arity,Clauses}|T], Dict0) ->
88
Dict = dict:store({local, Name,Arity}, Clauses, Dict0),
89
parse_to_dict(T, Dict);
90
parse_to_dict([{attribute,_,import,{Mod,Funcs}}|T], Dict0) ->
91
Dict = foldl(fun(I, D) ->
92
dict:store({remote,I}, Mod, D)
94
parse_to_dict(T, Dict);
95
parse_to_dict([_|T], Dict) ->
96
parse_to_dict(T, Dict);
97
parse_to_dict([], Dict) ->
100
%% make a temporary module name
103
{I,J,K} = erlang:now(),
104
Mod = list_to_atom("tmp" ++ integer_to_list(I) ++ integer_to_list(J) ++
106
{attribute,999,module, Mod}.
109
{Nerrs, L, Mode} = parse_file(File, 0, [], interpret),
110
{Nerrs, reverse(L), Mode}.
112
parse_file(File, Nerrs, L, Mode) ->
113
{ok, P} = file:open(File, read),
114
%% This is to skip the first line in the script
116
Ret = parse_loop(P, File, io:parse_erl_form(P, '', 2), Nerrs, L, Mode),
120
parse_include_file(File, Nerrs, L, Mode) ->
121
{ok, P} = file:open(File, read),
122
Ret = parse_loop(P, File, io:parse_erl_form(P, '', 1), Nerrs, L, Mode),
126
parse_loop(P, _, {eof,_}, Nerrs, L, Mode) ->
128
parse_loop(P, File, {ok, Form, Ln}, Nerrs, L0, Mode) ->
130
{attribute,_,mode,compile} ->
131
parse_loop(P,File,io:parse_erl_form(P,'',Ln),Nerrs,L0,compile);
132
{attribute,_,include,Include} ->
133
{Nerrs1, L1, Mode1} = parse_include_file(Include, Nerrs, L0, Mode),
134
parse_loop(P,File,io:parse_erl_form(P,'',Ln),Nerrs1,L1,Mode1);
136
parse_loop(P,File,io:parse_erl_form(P,'',Ln),Nerrs,[Form|L0],Mode)
138
parse_loop(P, File, {error,{Ln,Mod,Args}, Ln1}, Nerrs, L, Mode) ->
139
io:format("Error in File:~s Line:~w ~s~n",
140
[File, Ln, Mod:format_error(Args)]),
141
parse_loop(P, File, io:parse_erl_form(P, '', Ln1), Nerrs+1, L, Mode);
142
parse_loop(P, _, X, Nerrs, L, Mode) ->
143
io:format("Unexpected form:~p~n",[X]),
146
code_handler(local, [file], _, File) ->
148
code_handler(Name, Args, Dict, File) ->
149
%% io:format("code handler=~p~n",[{Name, Args}]),
150
Arity = length(Args),
151
case dict:find({local,Name,Arity}, Dict) of
153
LF = {value, fun(I, J) ->
154
code_handler(I, J, Dict, File)
156
case erl_eval:match_clause(Cs, Args,erl_eval:new_bindings(),LF) of
158
{value, Val, Bs1} = erl_eval:exprs(Body, Bs, LF),
161
io:format("escript: Fatal error"),
165
case dict:find({remote,{Name,Arity}}, Dict) of
167
%% io:format("Calling:~p~n",[{Mod,Name,Args}]),
168
apply(Mod, Name, Args);
170
io:format("Script does not export ~w/~w~n",