Huge progress
This commit is contained in:
parent
ed602ab3f3
commit
b78a2fa71a
5 changed files with 99 additions and 45 deletions
|
@ -72,6 +72,8 @@ probably never even happen.
|
||||||
|
|
||||||
## Development Resources
|
## Development Resources
|
||||||
|
|
||||||
|
+ http://erlang.org/doc/man/yecc.html
|
||||||
|
+ http://erlang.org/doc/man/leex.html
|
||||||
+ https://hexdocs.pm/elixir/syntax-reference.html#the-elixir-ast
|
+ https://hexdocs.pm/elixir/syntax-reference.html#the-elixir-ast
|
||||||
+ https://medium.com/cirru-project/resources-on-elixir-ast-e045b613f284
|
+ https://medium.com/cirru-project/resources-on-elixir-ast-e045b613f284
|
||||||
+ https://elixir-lang.org/getting-started/meta/quote-and-unquote.html
|
+ https://elixir-lang.org/getting-started/meta/quote-and-unquote.html
|
||||||
|
|
|
@ -31,7 +31,7 @@ defmodule Lytlang do
|
||||||
end
|
end
|
||||||
|
|
||||||
def parse(tokens, _opts \\ []) do
|
def parse(tokens, _opts \\ []) do
|
||||||
{:ok, [tree]} =
|
{:ok, tree} =
|
||||||
:lytlang_parser.parse(tokens)
|
:lytlang_parser.parse(tokens)
|
||||||
|> IO.inspect(label: "Parsed")
|
|> IO.inspect(label: "Parsed")
|
||||||
|
|
||||||
|
@ -40,10 +40,16 @@ defmodule Lytlang do
|
||||||
|
|
||||||
def eval_elixir(ast, opts \\ [])
|
def eval_elixir(ast, opts \\ [])
|
||||||
|
|
||||||
|
def eval_elixir(ast, _opts) when is_list(ast) do
|
||||||
|
{:__block__, [], ast}
|
||||||
|
|> IO.inspect(label: "Wrapped in Block")
|
||||||
|
|> eval_elixir()
|
||||||
|
end
|
||||||
|
|
||||||
def eval_elixir(ast, _opts) do
|
def eval_elixir(ast, _opts) do
|
||||||
{:__block__, [], [ast]}
|
ast
|
||||||
|> Code.eval_quoted()
|
|> Code.eval_quoted()
|
||||||
|> IO.inspect()
|
|> IO.inspect(label: "Evaluated as Elixir")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ Rules.
|
||||||
|
|
||||||
{D}+\.{D}+ : { token, { float, TokenLine, list_to_float(TokenChars) } }.
|
{D}+\.{D}+ : { token, { float, TokenLine, list_to_float(TokenChars) } }.
|
||||||
{D}+ : { token, { integer, TokenLine, list_to_integer(TokenChars) } }.
|
{D}+ : { token, { integer, TokenLine, list_to_integer(TokenChars) } }.
|
||||||
({L}|_)({U}{L}{D}|_)* : { token, var(TokenChars, TokenLine) }.
|
[{L}|_][{U}{L}{D}|_]+ : { token, var(TokenChars, TokenLine) }.
|
||||||
|
|
||||||
\+ : { token, { '+', TokenLine } }.
|
\+ : { token, { '+', TokenLine } }.
|
||||||
- : { token, { '-', TokenLine } }.
|
- : { token, { '-', TokenLine } }.
|
||||||
|
@ -22,8 +22,18 @@ Rules.
|
||||||
// : { token, { '//', TokenLine } }.
|
// : { token, { '//', TokenLine } }.
|
||||||
\( : { token, { '(', TokenLine } }.
|
\( : { token, { '(', TokenLine } }.
|
||||||
\) : { token, { ')', TokenLine } }.
|
\) : { token, { ')', TokenLine } }.
|
||||||
|
\[ : { token, { '[', TokenLine } }.
|
||||||
|
\] : { token, { ']', TokenLine } }.
|
||||||
|
\< : { token, { '<', TokenLine } }.
|
||||||
|
\> : { token, { '>', TokenLine } }.
|
||||||
|
\{ : { token, { '{', TokenLine } }.
|
||||||
|
\} : { token, { '}', TokenLine } }.
|
||||||
|
\" : { token, { '"', TokenLine } }.
|
||||||
|
\' : { token, { '\'', TokenLine } }.
|
||||||
|
, : { token, { ',', TokenLine } }.
|
||||||
= : { token, { '=', TokenLine } }.
|
= : { token, { '=', TokenLine } }.
|
||||||
-> : { token, { '->', TokenLine } }.
|
-> : { token, { '->', TokenLine } }.
|
||||||
|
: : { token, { ':', TokenLine } }.
|
||||||
; : { token, { eol, TokenLine } }.
|
; : { token, { eol, TokenLine } }.
|
||||||
{LF} : { token, { eol, TokenLine } }.
|
{LF} : { token, { eol, TokenLine } }.
|
||||||
|
|
||||||
|
|
|
@ -1,22 +1,8 @@
|
||||||
Nonterminals
|
Nonterminals
|
||||||
grammar
|
grammar e_list e assignment add sub mult div idiv unary number list map_el map.
|
||||||
e_list
|
|
||||||
e
|
|
||||||
assignment
|
|
||||||
add
|
|
||||||
sub
|
|
||||||
mult
|
|
||||||
div
|
|
||||||
idiv
|
|
||||||
unary
|
|
||||||
number
|
|
||||||
unary
|
|
||||||
.
|
|
||||||
|
|
||||||
Terminals
|
Terminals
|
||||||
var float integer eol
|
var float integer eol '+' '-' '*' '/' '//' '(' ')' '=' '"' '\'' '{' '}' '[' ']' '<' '>' ',' ':'.
|
||||||
'+' '-' '*' '/' '//' '(' ')' '='
|
|
||||||
.
|
|
||||||
|
|
||||||
Rootsymbol grammar.
|
Rootsymbol grammar.
|
||||||
Endsymbol '$end'.
|
Endsymbol '$end'.
|
||||||
|
@ -37,15 +23,13 @@ e_list -> e eol : ['$1'].
|
||||||
e_list -> eol e_list : '$2'.
|
e_list -> eol e_list : '$2'.
|
||||||
e_list -> e eol e_list : ['$1' | '$3'].
|
e_list -> e eol e_list : ['$1' | '$3'].
|
||||||
|
|
||||||
%% Minimum expressions
|
e -> '<' e ',' e '>' : {'$2', '$4'}.
|
||||||
e -> var : '$1'.
|
e -> '<' list '>' : {'{}', [], '$2'}.
|
||||||
|
|
||||||
|
e -> '[' ']' : [].
|
||||||
|
e -> var : ?var('$1').
|
||||||
e -> number : '$1'.
|
e -> number : '$1'.
|
||||||
e -> '(' e ')' : '$2'.
|
e -> '(' e ')' : '$2'.
|
||||||
|
|
||||||
%% Numbers
|
|
||||||
number -> float : '$1'.
|
|
||||||
number -> integer : ?e(3, '$1').
|
|
||||||
|
|
||||||
e -> mult : '$1'.
|
e -> mult : '$1'.
|
||||||
e -> div : '$1'.
|
e -> div : '$1'.
|
||||||
e -> idiv : '$1'.
|
e -> idiv : '$1'.
|
||||||
|
@ -53,26 +37,29 @@ e -> assignment : '$1'.
|
||||||
e -> add : '$1'.
|
e -> add : '$1'.
|
||||||
e -> sub : '$1'.
|
e -> sub : '$1'.
|
||||||
e -> unary : '$1'.
|
e -> unary : '$1'.
|
||||||
|
e -> '"' '"' : list_to_binary([]).
|
||||||
|
e -> '"' var '"' : list_to_binary('$2').
|
||||||
|
e -> '[' list ']' : '$2'.
|
||||||
|
e -> '{' map '}' : '$2'.
|
||||||
|
|
||||||
assignment -> var '=' e :
|
list -> '$empty' : [].
|
||||||
{ '=', ?meta('$2'), [?var('$1'), '$3'] }.
|
list -> e : ['$1'].
|
||||||
|
list -> e ',' list : ['$1' | '$3'].
|
||||||
|
|
||||||
%% Arithmetic operations
|
map_el -> var ':' e : {?e(3, '$1'), '$3'}.
|
||||||
add -> e '+' e :
|
|
||||||
{ '+', ?meta('$2'), ['$1', '$3'] }.
|
|
||||||
|
|
||||||
sub -> e '-' e :
|
map -> '$empty' : {'%{}', [], []}.
|
||||||
{ '-', ?meta('$2'), ['$1', '$3'] }.
|
map -> map_el : {'%{}', [], ['$1']}.
|
||||||
|
map -> map_el ',' map : {'%{}', [], ['$1' | '$3']}.
|
||||||
mult -> e '*' e :
|
|
||||||
{ '*', ?meta('$2'), ['$1', '$3'] }.
|
|
||||||
|
|
||||||
div -> e '/' e :
|
|
||||||
{ '/', ?meta('$2'), ['$1', '$3'] }.
|
|
||||||
|
|
||||||
idiv -> e '//' e :
|
|
||||||
{ 'div', ?meta('$2'), ['$1', '$3'] }.
|
|
||||||
|
|
||||||
|
number -> float : ?e(3, '$1').
|
||||||
|
number -> integer : ?e(3, '$1').
|
||||||
|
assignment -> var '=' e : { '=', ?meta('$2'), [?var('$1'), '$3'] }.
|
||||||
|
add -> e '+' e : { '+', ?meta('$2'), ['$1', '$3'] }.
|
||||||
|
sub -> e '-' e : { '-', ?meta('$2'), ['$1', '$3'] }.
|
||||||
|
mult -> e '*' e : { '*', ?meta('$2'), ['$1', '$3'] }.
|
||||||
|
div -> e '/' e : { '/', ?meta('$2'), ['$1', '$3'] }.
|
||||||
|
idiv -> e '//' e : { 'div', ?meta('$2'), ['$1', '$3'] }.
|
||||||
unary -> '+' e : { '+', ?meta('$1'), ?op('$1'), '$2' }.
|
unary -> '+' e : { '+', ?meta('$1'), ?op('$1'), '$2' }.
|
||||||
unary -> '-' e : { '-', ?meta('$1'), ?op('$1'), '$2' }.
|
unary -> '-' e : { '-', ?meta('$1'), ?op('$1'), '$2' }.
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
defmodule LytlangTest do
|
defmodule LytlangTest do
|
||||||
use ExUnit.Case
|
use ExUnit.Case, async: false
|
||||||
doctest Lytlang
|
doctest Lytlang
|
||||||
|
|
||||||
test "arithmetic" do
|
test "arithmetic" do
|
||||||
|
@ -16,10 +16,59 @@ defmodule LytlangTest do
|
||||||
{"8 / 4", 2.0},
|
{"8 / 4", 2.0},
|
||||||
{"8 // 4", 2},
|
{"8 // 4", 2},
|
||||||
{"a = 8\na + 9", 17},
|
{"a = 8\na + 9", 17},
|
||||||
|
{"a_number = 8\na_number + 9", 17},
|
||||||
{"2 + 3", 5}
|
{"2 + 3", 5}
|
||||||
]
|
]
|
||||||
|> Enum.map(fn {string, val} ->
|
|> Enum.map(fn {string, val} ->
|
||||||
assert Lytlang.eval(string) == val
|
assert Lytlang.eval(string) == val
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "lists" do
|
||||||
|
[
|
||||||
|
{"[]", []},
|
||||||
|
{"[2]", [2]},
|
||||||
|
{"[2, 3]", [2, 3]},
|
||||||
|
{"[2, [3, 4], [5, [6, [7]]]]", [2, [3, 4], [5, [6, [7]]]]},
|
||||||
|
{"[2, 3, 4, 5, 6, 7]", [2, 3, 4, 5, 6, 7]}
|
||||||
|
]
|
||||||
|
|> Enum.map(fn {string, val} ->
|
||||||
|
assert Lytlang.eval(string) == val
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "tuples" do
|
||||||
|
[
|
||||||
|
{"<>", {}},
|
||||||
|
{"<2>", {2}},
|
||||||
|
{"<2, 3>", {2, 3}},
|
||||||
|
{"<2, <3, 4>, <5, <6, <7>>>>", {2, {3, 4}, {5, {6, {7}}}}},
|
||||||
|
{"<2, 3, 4, 5, 6, 7>", {2, 3, 4, 5, 6, 7}}
|
||||||
|
]
|
||||||
|
|> Enum.map(fn {string, val} ->
|
||||||
|
assert Lytlang.eval(string) == val
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "strings" do
|
||||||
|
[
|
||||||
|
{"\"\"", ""},
|
||||||
|
{"\"abcd\"", "abcd"}
|
||||||
|
]
|
||||||
|
|> Enum.map(fn {string, val} ->
|
||||||
|
assert Lytlang.eval(string) == val
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "maps" do
|
||||||
|
[
|
||||||
|
{"{}", %{}},
|
||||||
|
{"{x : 9}", %{:x => 9}},
|
||||||
|
{"{x : 9}", %{x: 9}},
|
||||||
|
{"{x: 9}", %{x: 9}}
|
||||||
|
]
|
||||||
|
|> Enum.map(fn {string, val} ->
|
||||||
|
assert Lytlang.eval(string) == val
|
||||||
|
end)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue