Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -module(lang0).
- -compile(export_all).
- % About erlang language.
- function_name(AnyArg, [HeadOfList | TailOfList], {T, U, P, L, E}) ->
- % NO VARIABLES - only bindings. One bound with '=' could nevar change
- X = 1, % read: we make a predicate on X: X must be 1
- % X becomes bound to value 1
- X = 1, % X is still (and forever in this context) 1,
- 1 = X, % all is ok, 1 is equal to (matches) X
- X = 2, % oh, the erlang interpreter will loudly cry here:
- % X doesn't match 2, its 1!
- Y = 2 + X, % Y is 3 now
- Fun = fun (X) -> X + 1 end, % Fun is an incrementer now
- Y = Fun(2), % lol, erlang will eat this - both left and right are bound to 3
- some_atomic_shit, % it's an... atom. Like a string-constant, w/o bracets.
- module:some_function(X, HeadOfList), % qualified call
- [1, 2, 3], % list of three elems
- {1, 2, 3} = {T, U, P} % T, U and P must be 1, 2 and 3, or the program will
- % fall - otherwise it just accepts this clause.
- $a, % 'a' character
- $,, % ',' character
- $ , % ' ' character
- Fun. % returns Fun
- % Okay, parsers. I made them functions, returning string-eating mechanism.
- % parser resuls is
- % {ok, {Result, Context}},
- % {error, {Reason, Where}}
- % basic parser is char()
- test() ->
- Char = parser:char($a),
- {ok, {$a, "bc"}} = Char("abc"),
- {error, {{exprected, $a, but_found}, "dbc"}} = Char("dbc").
- % parser:any(List) tries to run any parser from list unless it succeeds.
- test_any() ->
- Any = parser:any([
- parser:char($a),
- parser:char($b)
- ]),
- {ok, {$a, "b"}} = Any("ab"),
- {error, {{exprected, $b, but_found}, "dbc"}} = Any("dbc").
- test_misc() ->
- Marked = parser:many( % many
- parser:marked(char, % - marked as char
- parser:any([ % - any of
- parser:char($a), % - a
- parser:char($b), % - b
- parser:char($c), % - c
- ])
- )
- ),
- {ok, {[{char, $a}, % returned list of {char, Char}
- {char, $b},
- {char, $a},
- {char, $c}],
- "def"}} = Marked("abacdef").
- % expression parser tries one of [lambda, application] parsers
- % and returns the first one matched
- expression() ->
- parser:any([
- lambda(),
- application()
- ]).
- % lambda parser
- lambda() ->
- parser:marked(lambda, % marks result as lambda
- parser:entuple([ % produces tuple containing:
- parser:many1_tokens(parser:name()), % - many space-separated names
- parser:token("->"), % - token(...) drops anything
- % it matches
- parser:enlist([ % - list, containing
- parser:return([]), % - it is here to prevent
- % RASPIDORASEELO
- parser:recuring( % - expression
- fun (_) -> % Just a recursion. Damn.
- expression()
- end)
- ])
- ])
- ).
- % application parser
- application() ->
- parser:marked(app, % mark the result as app[lication] "f x" - f to x
- parser:many1_tokens( % 1 or more
- terminal() % - terminals
- )
- ).
- % parser of terminals
- terminal() ->
- parser:any([ % terminal is one of:
- parser:marked(var, parser:name()), % - variable, marked 'var'
- parser:marked(const, parser:number()), % - const int, marked 'const'
- parser:inside( % - braceted...
- parser:token("("),
- parser:recuring(
- fun (_) -> expression() end), % - ...subexpression
- parser:token(")")
- )
- ]).
- compile(Program) ->
- E = expression(), % Build the parser - which is function
- {ok, {PC, _}} = E(Program), % Run it on program text and
- % match to structure. This code also ensures
- % the first element is 'ok'... or loudly falls.
- dispatch([], PC). % Compile into form the interpreter knows
- print(Program) ->
- P = compile(Program),
- lc:print(P). % lc is a interpreter module, it can print
- % prettily
- eval(Program) ->
- P = compile(Program),
- lc:eval(P).
- dispatch(Stack, {app, List}) ->
- lists:map(fun (X) -> dispatch(Stack, X) end, List);
- dispatch(Stack, {lambda, Args, "->", [Body]}) ->
- Head = lists:map(fun (_) -> l end, Args),
- Head ++ dispatch(Args ++ Stack, Body);
- dispatch(Stack, {var, Name}) ->
- N = number_of(Stack, Name),
- [var, N];
- dispatch(Stack, {const, List}) ->
- list_to_integer(List).
- number_of([X | List], X) -> 0;
- number_of([_ | List], X) -> 1 + number_of(List, X).
Add Comment
Please, Sign In to add comment