Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion lib/ex_pression/interpreter.ex
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,13 @@ defmodule ExPression.Interpreter do
args = Enum.map(args, &do_eval(&1, context))
arity = length(args)

# Ensure functions_module is loaded first so its atoms are available
_ = context.functions_module && Code.ensure_loaded?(context.functions_module)

with :ok <- args_find_error(args),
{:ok, f_name} <- string_to_existing_atom(name) do
cond do
context.functions_module && Code.ensure_loaded?(context.functions_module) &&
context.functions_module &&
Kernel.function_exported?(context.functions_module, f_name, arity) ->
safe_fun_call(context.functions_module, f_name, args)

Expand Down
24 changes: 12 additions & 12 deletions lib/ex_pression/parser/grammar.ex
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,27 @@ defmodule ExPression.Parser.Grammar do
def peg do
peg Expr do
# Space characters
S <- {' ', '\t', '\r', '\n'}
S <- {?\s, ?\t, ?\r, ?\n}

# Basic atoms
True <- ("True" | "true") * fn cs -> [true | cs] end
False <- ("False" | "false") * fn cs -> [false | cs] end
Null <- ("None" | "null") * fn cs -> [nil | cs] end

# Strings
Xdigit <- {'0'..'9', 'a'..'f', 'A'..'F'}
Unicode_escape <- 'u' * Xdigit[4]
Escape <- '\\' * ({'"', '\\', '/', 'b', 'f', 'n', 'r', 't'} | Unicode_escape)
String_body <- star(Escape) * star(+({'\x20'..'\x7f', 'а'..'я', 'А'..'Я', '\xC2\xA0'..'\xC2\xBF', '\xC3\x80'..'\xC3\xBF'} - {'"'} - {'\\'}) * star(Escape))
String <- '"' * str(String_body) * '"'
Xdigit <- {?0..?9, ?a..?f, ?A..?F}
Unicode_escape <- {?u} * Xdigit[4]
Escape <- {?\\} * ({?", ?\\, ?/, ?b, ?f, ?n, ?r, ?t} | Unicode_escape)
String_body <- star(Escape) * star(+({?\s..?~, ?а..?я, ?А..?Я, 0xA0..0xBF, 0xC0..0xFF} - {?"} - {?\\}) * star(Escape))
String <- {?"} * str(String_body) * {?"}

# Numbers
Integer <- int(opt('-') * ('0' | {'1'..'9'}) * star({'0'..'9'}))
Float <- float(opt('-') * ('0' | {'1'..'9'}) * star({'0'..'9'}) * (("." * +{'0'..'9'}) | ({'e', 'E'} * opt({'+', '-'}) * +{'0'..'9'})))
Integer <- int(opt("-") * ("0" | {?1..?9}) * star({?0..?9}))
Float <- float(opt("-") * ("0" | {?1..?9}) * star({?0..?9}) * (("." * +{?0..?9}) | ({?e, ?E} * opt({?+, ?-}) * +{?0..?9})))

KeyWord <- ("None" | "False" | "True" | "false" | "true" | "null" | "or" | "and" | "not")
IdentifierRest <- {'a'..'z', 'A'..'Z', '_', '0'..'9'}
Identifier1 <- {'a'..'z', 'A'..'Z', '_'} * star(IdentifierRest)
IdentifierRest <- {?a..?z, ?A..?Z, ?_, ?0..?9}
Identifier1 <- {?a..?z, ?A..?Z, ?_} * star(IdentifierRest)
Identifier <- str((KeyWord * Identifier1) | (!KeyWord * Identifier1))

# Expressions
Expand Down Expand Up @@ -88,14 +88,14 @@ defmodule ExPression.Parser.Grammar do
end
end

L5BinOp <- star(S) * str({'+', '-'}) * star(S) * L5 * fn [b, op, a | cs] ->
L5BinOp <- star(S) * str({?+, ?-}) * star(S) * L5 * fn [b, op, a | cs] ->
case op do
"+" -> [{:+, [a, b]} | cs]
"-" -> [{:-, [a, b]} | cs]
end
end

L6BinOp <- star(S) * str({'*', '/'}) * star(S) * L6 * fn [b, op, a | cs] ->
L6BinOp <- star(S) * str({?*, ?/}) * star(S) * L6 * fn [b, op, a | cs] ->
case op do
"*" -> [{:*, [a, b]} | cs]
"/" -> [{:/, [a, b]} | cs]
Expand Down
11 changes: 8 additions & 3 deletions mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,13 @@ defmodule ExPression.MixProject do
package: package(),
docs: docs(),
# Testing
test_coverage: [tool: ExCoveralls],
preferred_cli_env: [
test_coverage: [tool: ExCoveralls]
]
end

def cli do
[
preferred_envs: [
coveralls: :test,
"coveralls.detail": :test,
"coveralls.post": :test,
Expand All @@ -39,7 +44,7 @@ defmodule ExPression.MixProject do
# JSON Encode/Decode
{:jason, "~> 1.4"},
# PEG parser
{:xpeg2, "~> 0.9.0"},
{:xpeg2, github: "Houdini/xpeg2", branch: "fix-warnings-2"},
# DEV tools
# Test coverage
{:excoveralls, "~> 0.18.0", only: :test},
Expand Down
38 changes: 20 additions & 18 deletions mix.lock
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
%{
"bunt": {:hex, :bunt, "0.2.1", "e2d4792f7bc0ced7583ab54922808919518d0e57ee162901a16a1b6664ef3b14", [:mix], [], "hexpm", "a330bfb4245239787b15005e66ae6845c9cd524a288f0d141c148b02603777a5"},
"credo": {:hex, :credo, "1.7.2", "fdee3a7cb553d8f2e773569181f0a4a2bb7d192e27e325404cc31b354f59d68c", [:mix], [{:bunt, "~> 0.2.1 or ~> 1.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "dd15d6fbc280f6cf9b269f41df4e4992dee6615939653b164ef951f60afcb68e"},
"dialyxir": {:hex, :dialyxir, "1.4.3", "edd0124f358f0b9e95bfe53a9fcf806d615d8f838e2202a9f430d59566b6b53b", [:mix], [{:erlex, ">= 0.2.6", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "bf2cfb75cd5c5006bec30141b131663299c661a864ec7fbbc72dfa557487a986"},
"earmark_parser": {:hex, :earmark_parser, "1.4.39", "424642f8335b05bb9eb611aa1564c148a8ee35c9c8a8bba6e129d51a3e3c6769", [:mix], [], "hexpm", "06553a88d1f1846da9ef066b87b57c6f605552cfbe40d20bd8d59cc6bde41944"},
"erlex": {:hex, :erlex, "0.2.6", "c7987d15e899c7a2f34f5420d2a2ea0d659682c06ac607572df55a43753aa12e", [:mix], [], "hexpm", "2ed2e25711feb44d52b17d2780eabf998452f6efda104877a3881c2f8c0c0c75"},
"ex_doc": {:hex, :ex_doc, "0.31.0", "06eb1dfd787445d9cab9a45088405593dd3bb7fe99e097eaa71f37ba80c7a676", [:mix], [{:earmark_parser, "~> 1.4.39", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_c, ">= 0.1.1", [hex: :makeup_c, repo: "hexpm", optional: true]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1", [hex: :makeup_erlang, repo: "hexpm", optional: false]}], "hexpm", "5350cafa6b7f77bdd107aa2199fe277acf29d739aba5aee7e865fc680c62a110"},
"excoveralls": {:hex, :excoveralls, "0.18.0", "b92497e69465dc51bc37a6422226ee690ab437e4c06877e836f1c18daeb35da9", [:mix], [{:castore, "~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "1109bb911f3cb583401760be49c02cbbd16aed66ea9509fc5479335d284da60b"},
"file_system": {:hex, :file_system, "1.0.0", "b689cc7dcee665f774de94b5a832e578bd7963c8e637ef940cd44327db7de2cd", [:mix], [], "hexpm", "6752092d66aec5a10e662aefeed8ddb9531d79db0bc145bb8c40325ca1d8536d"},
"glob_ex": {:hex, :glob_ex, "0.1.6", "3a311ade50f6b71d638af660edcc844c3ab4eb2a2c816cfebb73a1d521bb2f9d", [:mix], [], "hexpm", "fda1e90e10f6029bd72967fef0c9891d0d14da89ca7163076e6028bfcb2c42fa"},
"jason": {:hex, :jason, "1.4.1", "af1504e35f629ddcdd6addb3513c3853991f694921b1b9368b0bd32beb9f1b63", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "fbb01ecdfd565b56261302f7e1fcc27c4fb8f32d56eab74db621fc154604a7a1"},
"makeup": {:hex, :makeup, "1.1.1", "fa0bc768698053b2b3869fa8a62616501ff9d11a562f3ce39580d60860c3a55e", [:mix], [{:nimble_parsec, "~> 1.2.2 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "5dc62fbdd0de44de194898b6710692490be74baa02d9d108bc29f007783b0b48"},
"makeup_elixir": {:hex, :makeup_elixir, "0.16.1", "cc9e3ca312f1cfeccc572b37a09980287e243648108384b97ff2b76e505c3555", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2.3 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "e127a341ad1b209bd80f7bd1620a15693a9908ed780c3b763bccf7d200c767c6"},
"makeup_erlang": {:hex, :makeup_erlang, "0.1.3", "d684f4bac8690e70b06eb52dad65d26de2eefa44cd19d64a8095e1417df7c8fd", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "b78dc853d2e670ff6390b605d807263bf606da3c82be37f9d7f68635bd886fc9"},
"nimble_parsec": {:hex, :nimble_parsec, "1.4.0", "51f9b613ea62cfa97b25ccc2c1b4216e81df970acd8e16e8d1bdc58fef21370d", [:mix], [], "hexpm", "9c565862810fb383e9838c1dd2d7d2c437b3d13b267414ba6af33e50d2d1cf28"},
"recode": {:hex, :recode, "0.6.5", "067335c383e807c1a6f5df22a92856f83e852f1acdbedaa2cced52df082dbe25", [:mix], [{:bunt, "~> 0.2", [hex: :bunt, repo: "hexpm", optional: false]}, {:glob_ex, "~> 0.1", [hex: :glob_ex, repo: "hexpm", optional: false]}, {:rewrite, "~> 0.9", [hex: :rewrite, repo: "hexpm", optional: false]}], "hexpm", "d03c66c1dd1ca5b19ad14a3a5fbb2218060352e91d4ad7925fb52f1915a4aabe"},
"rewrite": {:hex, :rewrite, "0.10.0", "5d756b6dc67679e7156ff6055f9654be02dbaeb177aaf1ff6af7ee8da8718248", [:mix], [{:glob_ex, "~> 0.1", [hex: :glob_ex, repo: "hexpm", optional: false]}, {:sourceror, "~> 0.13", [hex: :sourceror, repo: "hexpm", optional: false]}], "hexpm", "68d7808cf549e7bf51b0119a8edc14d50970bad479115249030baa580c1d7b50"},
"sourceror": {:hex, :sourceror, "0.14.1", "c6fb848d55bd34362880da671debc56e77fd722fa13b4dcbeac89a8998fc8b09", [:mix], [], "hexpm", "8b488a219e4c4d7d9ff29d16346fd4a5858085ccdd010e509101e226bbfd8efc"},
"xpeg2": {:hex, :xpeg2, "0.9.0", "0a91064dfb6b9e3168eaf5d5c8f01a892329941b9e51c93a458b6bce408e4ec5", [:mix], [], "hexpm", "91152bcb0fcaf09284a7ac90ac8c4267491da70d11efcbdb21ce3d3cdb036b5d"},
"bunt": {:hex, :bunt, "1.0.0", "081c2c665f086849e6d57900292b3a161727ab40431219529f13c4ddcf3e7a44", [:mix], [], "hexpm", "dc5f86aa08a5f6fa6b8096f0735c4e76d54ae5c9fa2c143e5a1fc7c1cd9bb6b5"},
"credo": {:hex, :credo, "1.7.16", "a9f1389d13d19c631cb123c77a813dbf16449a2aebf602f590defa08953309d4", [:mix], [{:bunt, "~> 0.2.1 or ~> 1.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "d0562af33756b21f248f066a9119e3890722031b6d199f22e3cf95550e4f1579"},
"dialyxir": {:hex, :dialyxir, "1.4.7", "dda948fcee52962e4b6c5b4b16b2d8fa7d50d8645bbae8b8685c3f9ecb7f5f4d", [:mix], [{:erlex, ">= 0.2.8", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "b34527202e6eb8cee198efec110996c25c5898f43a4094df157f8d28f27d9efe"},
"earmark_parser": {:hex, :earmark_parser, "1.4.44", "f20830dd6b5c77afe2b063777ddbbff09f9759396500cdbe7523efd58d7a339c", [:mix], [], "hexpm", "4778ac752b4701a5599215f7030989c989ffdc4f6df457c5f36938cc2d2a2750"},
"erlex": {:hex, :erlex, "0.2.8", "cd8116f20f3c0afe376d1e8d1f0ae2452337729f68be016ea544a72f767d9c12", [:mix], [], "hexpm", "9d66ff9fedf69e49dc3fd12831e12a8a37b76f8651dd21cd45fcf5561a8a7590"},
"escape": {:hex, :escape, "0.4.1", "065164d0d18a70e75092fc71124978e7b50ac99de69748739e48609825ab1c9e", [:mix], [], "hexpm", "867d641d66ffb1afbb1cdf872eff3c21b1af90fec3d21916b1b5eda51e244158"},
"ex_doc": {:hex, :ex_doc, "0.40.1", "67542e4b6dde74811cfd580e2c0149b78010fd13001fda7cfeb2b2c2ffb1344d", [:mix], [{:earmark_parser, "~> 1.4.44", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_c, ">= 0.1.0", [hex: :makeup_c, repo: "hexpm", optional: true]}, {:makeup_elixir, "~> 0.14 or ~> 1.0", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1 or ~> 1.0", [hex: :makeup_erlang, repo: "hexpm", optional: false]}, {:makeup_html, ">= 0.1.0", [hex: :makeup_html, repo: "hexpm", optional: true]}], "hexpm", "bcef0e2d360d93ac19f01a85d58f91752d930c0a30e2681145feea6bd3516e00"},
"excoveralls": {:hex, :excoveralls, "0.18.5", "e229d0a65982613332ec30f07940038fe451a2e5b29bce2a5022165f0c9b157e", [:mix], [{:castore, "~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "523fe8a15603f86d64852aab2abe8ddbd78e68579c8525ae765facc5eae01562"},
"file_system": {:hex, :file_system, "1.1.1", "31864f4685b0148f25bd3fbef2b1228457c0c89024ad67f7a81a3ffbc0bbad3a", [:mix], [], "hexpm", "7a15ff97dfe526aeefb090a7a9d3d03aa907e100e262a0f8f7746b78f8f87a5d"},
"glob_ex": {:hex, :glob_ex, "0.1.11", "cb50d3f1ef53f6ca04d6252c7fde09fd7a1cf63387714fe96f340a1349e62c93", [:mix], [], "hexpm", "342729363056e3145e61766b416769984c329e4378f1d558b63e341020525de4"},
"jason": {:hex, :jason, "1.4.4", "b9226785a9aa77b6857ca22832cffa5d5011a667207eb2a0ad56adb5db443b8a", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "c5eb0cab91f094599f94d55bc63409236a8ec69a21a67814529e8d5f6cc90b3b"},
"makeup": {:hex, :makeup, "1.2.1", "e90ac1c65589ef354378def3ba19d401e739ee7ee06fb47f94c687016e3713d1", [:mix], [{:nimble_parsec, "~> 1.4", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "d36484867b0bae0fea568d10131197a4c2e47056a6fbe84922bf6ba71c8d17ce"},
"makeup_elixir": {:hex, :makeup_elixir, "1.0.1", "e928a4f984e795e41e3abd27bfc09f51db16ab8ba1aebdba2b3a575437efafc2", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2.3 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "7284900d412a3e5cfd97fdaed4f5ed389b8f2b4cb49efc0eb3bd10e2febf9507"},
"makeup_erlang": {:hex, :makeup_erlang, "1.0.3", "4252d5d4098da7415c390e847c814bad3764c94a814a0b4245176215615e1035", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "953297c02582a33411ac6208f2c6e55f0e870df7f80da724ed613f10e6706afd"},
"nimble_parsec": {:hex, :nimble_parsec, "1.4.2", "8efba0122db06df95bfaa78f791344a89352ba04baedd3849593bfce4d0dc1c6", [:mix], [], "hexpm", "4b21398942dda052b403bbe1da991ccd03a053668d147d53fb8c4e0efe09c973"},
"recode": {:hex, :recode, "0.8.0", "4e324f608fbac8a01794902703ba04fa1aaab25217108410f7a0cdcecdb1027c", [:mix], [{:escape, "~> 0.1", [hex: :escape, repo: "hexpm", optional: false]}, {:glob_ex, "~> 0.1", [hex: :glob_ex, repo: "hexpm", optional: false]}, {:rewrite, "~> 1.2", [hex: :rewrite, repo: "hexpm", optional: false]}], "hexpm", "c71d24ebb5a460679d55f8e27585f83542787e238f5a317162ee8e77de74ebba"},
"rewrite": {:hex, :rewrite, "1.2.0", "80220eb14010e175b67c939397e1a8cdaa2c32db6e2e0a9d5e23e45c0414ce21", [:mix], [{:glob_ex, "~> 0.1", [hex: :glob_ex, repo: "hexpm", optional: false]}, {:sourceror, "~> 1.0", [hex: :sourceror, repo: "hexpm", optional: false]}, {:text_diff, "~> 0.1", [hex: :text_diff, repo: "hexpm", optional: false]}], "hexpm", "a1cd702bbb9d51613ab21091f04a386d750fc6f4516b81900df082d78b2d8c50"},
"sourceror": {:hex, :sourceror, "1.10.1", "325753ed460fe9fa34ebb4deda76d57b2e1507dcd78a5eb9e1c41bfb78b7cdfe", [:mix], [], "hexpm", "288f3079d93865cd1e3e20df5b884ef2cb440e0e03e8ae393624ee8a770ba588"},
"text_diff": {:hex, :text_diff, "0.1.0", "1caf3175e11a53a9a139bc9339bd607c47b9e376b073d4571c031913317fecaa", [:mix], [], "hexpm", "d1ffaaecab338e49357b6daa82e435f877e0649041ace7755583a0ea3362dbd7"},
"xpeg2": {:git, "https://github.com/Houdini/xpeg2.git", "42e4a7b3cf36ce35b7b811014aed715c5f641861", [branch: "fix-warnings-2"]},
}
Loading