Skip to content
astCounter.erl 3.18 KiB
Newer Older
Carlos Galindo's avatar
Carlos Galindo committed
-module(astCounter).
-compile(export_all).

% Call: astCounter:enterDeepestDir("ComputedSlices/erlsom/","erlsom").
enterDeepestDir(FileDir,Set) ->
	enterDeepestDir(FileDir,Set,[]).

enterDeepestDir(FileDir,Set,FolderList) ->
	AdditionalRoute = lists:foldr(fun(F,Acc) -> Acc ++ F ++ "/" end, "",FolderList),
	{ok,Files} = file:list_dir(FileDir++AdditionalRoute),
	InnerDirs = lists:filter(fun(F) -> filelib:is_dir(FileDir++AdditionalRoute++F) end, Files),
	case InnerDirs of
		[] ->
			countASTsNodes(FileDir,Set,FolderList); % TODO: VALIDAR FUNCIONAMIENTO
		_ ->
			lists:map(fun(D) -> enterDeepestDir(FileDir,Set,[D|FolderList]) end, InnerDirs)
	end.

% THIS CLAUSE IS ONLY VALID FOR DIRECTORY STRUCTURE => $PWD/program.erl
countASTsNodes(FileDir,_Set,[]) ->
    FilePath = FileDir,
	[LastFolder | _] = lists:reverse(filename:split(FileDir)),
	{ok,Fd} = file:open("Results/results"++LastFolder++".txt",[append]),
	Files = lists:sort(getErlFiles(FilePath)),
	lists:map(fun(F) ->
				Nodes = counter(FilePath ++ F),
				io:format(Fd,"File: ~s => ~w AST Nodes\n",[F,Nodes])
			  end,
			  Files),
	file:close(Fd);

countASTsNodes(FileDir,Set,FolderList) ->
    % THIS CLAUSE IS ONLY VALID FOR DIRECTORY STRUCTURE => $PWD/benchName/program.erl
	BenchName = case length(FolderList) of
		1 -> [Name] = FolderList,
		     Name;
		N -> throw("MORE/LESS THAN 2 ELEMENTS: " ++ N)
	end,
	FilePath = FileDir ++ BenchName ++ "/",
	[LastFolder | _] = lists:reverse(filename:split(FilePath)),
	filelib:ensure_dir("Results/"++Set++"/"),
	{ok,Fd} = file:open("Results/"++Set++"/"++LastFolder++".txt",[append]),
	Files = lists:sort(getErlFiles(FilePath)),
	lists:map(fun(F) -> 
				Nodes = counter(FilePath ++ F),
				Fname = filename:basename(F,".erl"),
                [Graph,Crit] = string:split(Fname,"_"),
				io:format(Fd,"~s;~s;~s;~w\n",[BenchName,Graph,"#"++Crit,Nodes])
			  end,
			  Files),
	file:close(Fd).

getErlFiles(Filename) ->
	case file:list_dir(Filename) of
		{ok,Names} -> 
			lists:filter(fun(File) -> filename:extension(File) == ".erl" end, Names);
		_ -> throw("The file does not exist")
	end.

counter(File) ->
	FunctionForms = getAST(File),
	lists:foldl(fun countNodes/2, 0, FunctionForms).

getAST(File) ->
	{ok, Forms} = epp:parse_file(File, [], []),
	lists:filter(fun(Form) -> element(1,Form) == function end, Forms).

countNodes(Form, NumNodes) ->
	erl_syntax_lib:fold(fun(N,Acc) ->
							case erl_syntax:type(N) of
								atom -> 
									case erl_syntax:atom_literal(N) of
                                        "sliced" -> Acc;
                                        _ -> Acc + 1
                                    end;
								underscore -> 
									Acc;
								_ ->
									Acc + 1
							end
						end, NumNodes, Form).

fileCounter(Path,FolderList) ->
	AdditionalRoute = lists:foldr(fun(F,Acc) -> Acc ++ F ++ "/" end, "",FolderList),
	{ok,Files} = file:list_dir(Path++AdditionalRoute),
	InnerDirs = lists:filter(fun(F) -> filelib:is_dir(Path++AdditionalRoute++F) end, Files),
	case InnerDirs of
		[] ->
			io:format("Slices in ~s => ~p\n",[AdditionalRoute,length(getErlFiles(Path++AdditionalRoute))/2]);
		_ ->
			lists:map(fun(D) -> fileCounter(Path,[D|FolderList]) end, InnerDirs)
	end.

printer(N) -> io:format("Node: ~w\n",[N]).