mirror of
https://github.com/KevinMidboe/linguist.git
synced 2025-10-29 09:40:21 +00:00
add erlang, more-complex shell examples
- some Erlang and escript files - .escript extension - .erlang extension - shell script with %, ##, name tokens
This commit is contained in:
21
samples/Erlang/factorial.script!
Executable file
21
samples/Erlang/factorial.script!
Executable file
@@ -0,0 +1,21 @@
|
||||
#!/usr/bin/env escript
|
||||
%% -*- erlang -*-
|
||||
%%! -smp enable -sname factorial -mnesia debug verbose
|
||||
main([String]) ->
|
||||
try
|
||||
N = list_to_integer(String),
|
||||
F = fac(N),
|
||||
io:format("factorial ~w = ~w\n", [N,F])
|
||||
catch
|
||||
_:_ ->
|
||||
usage()
|
||||
end;
|
||||
main(_) ->
|
||||
usage().
|
||||
|
||||
usage() ->
|
||||
io:format("usage: factorial integer\n"),
|
||||
halt(1).
|
||||
|
||||
fac(0) -> 1;
|
||||
fac(N) -> N * fac(N-1).
|
||||
4
samples/Erlang/hello.escript
Executable file
4
samples/Erlang/hello.escript
Executable file
@@ -0,0 +1,4 @@
|
||||
#!/usr/bin/env escript
|
||||
-export([main/1]).
|
||||
|
||||
main([]) -> io:format("Hello, World!~n").
|
||||
136
samples/Erlang/record_helper.erl
Normal file
136
samples/Erlang/record_helper.erl
Normal file
@@ -0,0 +1,136 @@
|
||||
%% For each header file, it scans thru all records and create helper functions
|
||||
%% Helper functions are:
|
||||
%% setters, getters, fields, fields_atom, type
|
||||
|
||||
-module(record_helper).
|
||||
|
||||
-export([make/1, make/2]).
|
||||
|
||||
make(HeaderFiles) ->
|
||||
make([ atom_to_list(X) || X <- HeaderFiles ], ".").
|
||||
|
||||
%% .hrl file, relative to current dir
|
||||
make(HeaderFiles, OutDir) ->
|
||||
ModuleName = "record_utils",
|
||||
HeaderComment = "%% This is auto generated file. Please don't edit it\n\n",
|
||||
ModuleDeclaration = "-module(" ++ ModuleName ++ ").\n"
|
||||
++ "-author(\"trung@mdkt.org\").\n"
|
||||
++ "-compile(export_all).\n"
|
||||
++ [ "-include(\"" ++ X ++ "\").\n" || X <- HeaderFiles ]
|
||||
++ "\n",
|
||||
Src = format_src(lists:sort(lists:flatten([read(X) || X <- HeaderFiles] ++ [generate_type_default_function()]))),
|
||||
file:write_file(OutDir++"/" ++ ModuleName ++ ".erl", list_to_binary([HeaderComment, ModuleDeclaration, Src])).
|
||||
|
||||
read(HeaderFile) ->
|
||||
try epp:parse_file(HeaderFile,[],[]) of
|
||||
{ok, Tree} ->
|
||||
parse(Tree);
|
||||
{error, Error} ->
|
||||
{error, {"Error parsing header file", HeaderFile, Error}}
|
||||
catch
|
||||
_:Error ->
|
||||
{catched_error, {"Error parsing header file", HeaderFile, Error}}
|
||||
end.
|
||||
|
||||
format_src([{_, _, _, Src}|T]) when length(T) == 0 ->
|
||||
Src ++ ".\n\n";
|
||||
format_src([{Type, _, _, Src}|[{Type, A, B, NSrc}|T]]) ->
|
||||
Src ++ ";\n\n" ++ format_src([{Type, A, B, NSrc}|T]);
|
||||
format_src([{_Type, _, _, Src}|[{Type1, A, B, NSrc}|T]]) ->
|
||||
Src ++ ".\n\n" ++ format_src([{Type1, A, B, NSrc}|T]);
|
||||
format_src([{_, _, _, Src}|T]) when length(T) > 0 ->
|
||||
Src ++ ";\n\n" ++ format_src(T).
|
||||
|
||||
parse(Tree) ->
|
||||
[ parse_record(X) || X <- Tree ].
|
||||
|
||||
parse_record({attribute, _, record, RecordInfo}) ->
|
||||
{RecordName, RecordFields} = RecordInfo,
|
||||
if
|
||||
length(RecordFields) == 1 ->
|
||||
lists:flatten([ generate_setter_getter_function(RecordName, X) || X <- RecordFields ]
|
||||
++ [generate_type_function(RecordName)]);
|
||||
true ->
|
||||
lists:flatten([generate_fields_function(RecordName, RecordFields)]
|
||||
++ [generate_fields_atom_function(RecordName, RecordFields)]
|
||||
++ [ generate_setter_getter_function(RecordName, X) || X <- RecordFields ]
|
||||
++ [generate_type_function(RecordName)])
|
||||
end;
|
||||
parse_record(_) -> [].
|
||||
|
||||
parse_field_name({record_field, _, {atom, _, FieldName}}) ->
|
||||
{field, "\"" ++ atom_to_list(FieldName) ++ "\""};
|
||||
parse_field_name({record_field, _, {atom, _, _FieldName}, {record, _, ParentRecordName, _}}) ->
|
||||
{parent_field, "fields(" ++ atom_to_list(ParentRecordName) ++ ")"};
|
||||
parse_field_name({record_field, _, {atom, _, FieldName}, _}) ->
|
||||
{field, "\"" ++ atom_to_list(FieldName) ++ "\""}.
|
||||
|
||||
parse_field_name_atom({record_field, _, {atom, _, FieldName}}) ->
|
||||
atom_to_list(FieldName);
|
||||
parse_field_name_atom({record_field, _, {atom, _, _FieldName}, {record, _, ParentRecordName, _}}) ->
|
||||
"fields_atom(" ++ atom_to_list(ParentRecordName) ++ ")";
|
||||
parse_field_name_atom({record_field, _, {atom, _, FieldName}, _}) ->
|
||||
atom_to_list(FieldName).
|
||||
|
||||
concat([], _S) -> [];
|
||||
concat([F|T], _S) when length(T) == 0 -> F;
|
||||
concat([F|T], S) -> F ++ S ++ concat(T, S).
|
||||
|
||||
concat_ext([], _S) -> [];
|
||||
concat_ext([F|T], S) -> F ++ S ++ concat_ext(T, S).
|
||||
|
||||
parse_field([], AccFields, AccParentFields) -> concat_ext(AccParentFields, " ++ ") ++ "[" ++ concat(AccFields, ", ") ++ "]";
|
||||
%parse_field([F|T], AccFields, AccParentFields) when length(T) == 0 -> parse_field_name(F);
|
||||
parse_field([F|T], AccFields, AccParentFields) ->
|
||||
case parse_field_name(F) of
|
||||
{field, Field} ->
|
||||
parse_field(T, AccFields ++ [Field], AccParentFields);
|
||||
{parent_field, PField} ->
|
||||
parse_field(T, AccFields, AccParentFields ++ [PField])
|
||||
end.
|
||||
|
||||
parse_field_atom([F|T]) when length(T) == 0 -> parse_field_name_atom(F);
|
||||
parse_field_atom([F|T]) ->
|
||||
parse_field_name_atom(F) ++ ", " ++ parse_field_atom(T).
|
||||
|
||||
generate_type_default_function() ->
|
||||
{type, zzz, 99, "type(_) -> undefined"}.
|
||||
|
||||
generate_type_function(RecordName) ->
|
||||
{type, RecordName, 0, "type(Obj) when is_record(Obj, " ++ atom_to_list(RecordName) ++ ") -> " ++ atom_to_list(RecordName)}.
|
||||
|
||||
generate_fields_function(RecordName, RecordFields) ->
|
||||
Fields = parse_field(RecordFields, [], []),
|
||||
{field, RecordName, 1, "fields(" ++ atom_to_list(RecordName) ++ ") -> \n\t" ++ Fields}.
|
||||
|
||||
generate_fields_atom_function(RecordName, RecordFields) ->
|
||||
Fields = parse_field_atom(RecordFields),
|
||||
{field_atom, RecordName, 1, "fields_atom(" ++ atom_to_list(RecordName) ++ ") -> \n\tlists:flatten([" ++ Fields ++ "])"}.
|
||||
|
||||
generate_setter_getter_function(RecordName, {record_field, _, {atom, _, FieldName}, {record, _, ParentRecordName, _}}) ->
|
||||
to_setter_getter_function(atom_to_list(RecordName), atom_to_list(FieldName), atom_to_list(ParentRecordName));
|
||||
generate_setter_getter_function(RecordName, {record_field, _, {atom, _, FieldName}, _}) ->
|
||||
to_setter_getter_function(atom_to_list(RecordName), atom_to_list(FieldName));
|
||||
generate_setter_getter_function(RecordName, {record_field, _, {atom, _, FieldName}}) ->
|
||||
to_setter_getter_function(atom_to_list(RecordName), atom_to_list(FieldName)).
|
||||
|
||||
to_setter_getter_function(RecordName, FieldName) ->
|
||||
[{setter, RecordName, 1, "set(Obj, " ++ FieldName ++ ", Value) when is_record(Obj, " ++ RecordName ++ ") -> \n"
|
||||
++ "\tNewObj = Obj#" ++ RecordName ++ "{" ++ FieldName ++ " = Value},\n"
|
||||
++ "\t{ok, NewObj, {" ++ FieldName ++ ", Value}}"},
|
||||
{getter, RecordName, 1, "get(Obj, " ++ FieldName ++ ") when is_record(Obj, " ++ RecordName ++ ") -> \n"
|
||||
++ "\t{ok, Obj#" ++ RecordName ++ "." ++ FieldName ++ "}"}
|
||||
].
|
||||
|
||||
to_setter_getter_function(RecordName, FieldName, ParentRecordName) ->
|
||||
[{setter, RecordName, 2, "set(Obj, " ++ FieldName ++ ", Value) when is_record(Obj, " ++ RecordName ++ ") and is_record(Value, " ++ ParentRecordName ++ ") -> \n"
|
||||
++ "\tNewObj = Obj#" ++ RecordName ++ "{" ++ FieldName ++ " = Value},\n"
|
||||
++ "\t{ok, NewObj, {" ++ FieldName ++ ", Value}};\n\n"
|
||||
++ "set(Obj, ParentProperty, Value) when is_record(Obj, " ++ RecordName ++ ") and is_atom(ParentProperty) -> \n"
|
||||
++ "\t{ok, NewParentObject, _} = set(Obj#" ++ RecordName ++ ".parent, ParentProperty, Value),\n"
|
||||
++ "\tset(Obj, parent, NewParentObject)"},
|
||||
{getter, RecordName, 2, "get(Obj, " ++ FieldName ++ ") when is_record(Obj, " ++ RecordName ++ ") -> \n"
|
||||
++ "\t{ok, Obj#" ++ RecordName ++ "." ++ FieldName ++ "};\n\n"
|
||||
++ "get(Obj, ParentProperty) when is_record(Obj, " ++ RecordName ++ ") and is_atom(ParentProperty) -> \n"
|
||||
++ "\tget(Obj#" ++ RecordName ++ ".parent, ParentProperty)"}
|
||||
].
|
||||
100
samples/Erlang/record_utils.erl
Normal file
100
samples/Erlang/record_utils.erl
Normal file
@@ -0,0 +1,100 @@
|
||||
%% This is auto generated file. Please don't edit it
|
||||
|
||||
-module(record_utils).
|
||||
-compile(export_all).
|
||||
-include("messages.hrl").
|
||||
|
||||
fields(abstract_message) ->
|
||||
["clientId", "destination", "messageId", "timestamp", "timeToLive", "headers", "body"];
|
||||
|
||||
fields(async_message) ->
|
||||
fields(abstract_message) ++ ["correlationId", "correlationIdBytes"].
|
||||
|
||||
fields_atom(abstract_message) ->
|
||||
lists:flatten([clientId, destination, messageId, timestamp, timeToLive, headers, body]);
|
||||
|
||||
fields_atom(async_message) ->
|
||||
lists:flatten([fields_atom(abstract_message), correlationId, correlationIdBytes]).
|
||||
|
||||
get(Obj, body) when is_record(Obj, abstract_message) ->
|
||||
{ok, Obj#abstract_message.body};
|
||||
|
||||
get(Obj, clientId) when is_record(Obj, abstract_message) ->
|
||||
{ok, Obj#abstract_message.clientId};
|
||||
|
||||
get(Obj, destination) when is_record(Obj, abstract_message) ->
|
||||
{ok, Obj#abstract_message.destination};
|
||||
|
||||
get(Obj, headers) when is_record(Obj, abstract_message) ->
|
||||
{ok, Obj#abstract_message.headers};
|
||||
|
||||
get(Obj, messageId) when is_record(Obj, abstract_message) ->
|
||||
{ok, Obj#abstract_message.messageId};
|
||||
|
||||
get(Obj, timeToLive) when is_record(Obj, abstract_message) ->
|
||||
{ok, Obj#abstract_message.timeToLive};
|
||||
|
||||
get(Obj, timestamp) when is_record(Obj, abstract_message) ->
|
||||
{ok, Obj#abstract_message.timestamp};
|
||||
|
||||
get(Obj, correlationId) when is_record(Obj, async_message) ->
|
||||
{ok, Obj#async_message.correlationId};
|
||||
|
||||
get(Obj, correlationIdBytes) when is_record(Obj, async_message) ->
|
||||
{ok, Obj#async_message.correlationIdBytes};
|
||||
|
||||
get(Obj, parent) when is_record(Obj, async_message) ->
|
||||
{ok, Obj#async_message.parent};
|
||||
|
||||
get(Obj, ParentProperty) when is_record(Obj, async_message) and is_atom(ParentProperty) ->
|
||||
get(Obj#async_message.parent, ParentProperty).
|
||||
|
||||
set(Obj, body, Value) when is_record(Obj, abstract_message) ->
|
||||
NewObj = Obj#abstract_message{body = Value},
|
||||
{ok, NewObj, {body, Value}};
|
||||
|
||||
set(Obj, clientId, Value) when is_record(Obj, abstract_message) ->
|
||||
NewObj = Obj#abstract_message{clientId = Value},
|
||||
{ok, NewObj, {clientId, Value}};
|
||||
|
||||
set(Obj, destination, Value) when is_record(Obj, abstract_message) ->
|
||||
NewObj = Obj#abstract_message{destination = Value},
|
||||
{ok, NewObj, {destination, Value}};
|
||||
|
||||
set(Obj, headers, Value) when is_record(Obj, abstract_message) ->
|
||||
NewObj = Obj#abstract_message{headers = Value},
|
||||
{ok, NewObj, {headers, Value}};
|
||||
|
||||
set(Obj, messageId, Value) when is_record(Obj, abstract_message) ->
|
||||
NewObj = Obj#abstract_message{messageId = Value},
|
||||
{ok, NewObj, {messageId, Value}};
|
||||
|
||||
set(Obj, timeToLive, Value) when is_record(Obj, abstract_message) ->
|
||||
NewObj = Obj#abstract_message{timeToLive = Value},
|
||||
{ok, NewObj, {timeToLive, Value}};
|
||||
|
||||
set(Obj, timestamp, Value) when is_record(Obj, abstract_message) ->
|
||||
NewObj = Obj#abstract_message{timestamp = Value},
|
||||
{ok, NewObj, {timestamp, Value}};
|
||||
|
||||
set(Obj, correlationId, Value) when is_record(Obj, async_message) ->
|
||||
NewObj = Obj#async_message{correlationId = Value},
|
||||
{ok, NewObj, {correlationId, Value}};
|
||||
|
||||
set(Obj, correlationIdBytes, Value) when is_record(Obj, async_message) ->
|
||||
NewObj = Obj#async_message{correlationIdBytes = Value},
|
||||
{ok, NewObj, {correlationIdBytes, Value}};
|
||||
|
||||
set(Obj, parent, Value) when is_record(Obj, async_message) and is_record(Value, abstract_message) ->
|
||||
NewObj = Obj#async_message{parent = Value},
|
||||
{ok, NewObj, {parent, Value}};
|
||||
|
||||
set(Obj, ParentProperty, Value) when is_record(Obj, async_message) and is_atom(ParentProperty) ->
|
||||
{ok, NewParentObject, _} = set(Obj#async_message.parent, ParentProperty, Value),
|
||||
set(Obj, parent, NewParentObject).
|
||||
|
||||
type(Obj) when is_record(Obj, abstract_message) -> abstract_message;
|
||||
|
||||
type(Obj) when is_record(Obj, async_message) -> async_message;
|
||||
|
||||
type(_) -> undefined.
|
||||
Reference in New Issue
Block a user