narrowtux / abacus

Parses and evaluates mathematical expressions in Elixir. Inspired by math.js
MIT License
84 stars 18 forks source link

Introduce a simple function to check expression syntax #8

Closed am-kantox closed 6 years ago

am-kantox commented 7 years ago

Easy one.

Is it possible to introduce Abacus.syntax?/[1,2] function, returning {:ok} / {:error, extended_info}? It might be quite handy in case of deferred operations. In my use case, I accept an expression as, say, user input, and execute it later on some alert. I would appreciate having an ability to inform the user that the expression introduced has syntax glitches.

I could provide a pull request for just this feature, but I think it’s up to you to decide whether you want to use it also in eval/[1,2], or not.

narrowtux commented 7 years ago

Abacus.parse already kind of does this, you could match the result in a case like this:

case Abacus.parse(user_input) do
  {:ok, _} -> #valid
  {:error, description} -> #notify user
end
narrowtux commented 7 years ago

I do have to fix an aspect about it though, that is that it can still crash if the lexer has a problem with the input. When I have fixed this, you'll be able to completely validate user input with parse.

narrowtux commented 7 years ago

Also, I should probably work more on better error reports, so it includes the column in the input and a better description of what went wrong so it's easier for your to present this to the user.

Input: 1+)
         ^
Unexpected Token '('.

This is a bit harder to do though so I will open another issue about this.

am-kantox commented 7 years ago

I am aware of parse. The main issue with it is that it won’t check for invalid scope (e. g. typo in scope’s variables.) AFAIU, a + b would return :ok despite whether the backend is aware of both a and b.

I understand, that it would require some additional coding on top of lexer, but I believe it worth it.

narrowtux commented 7 years ago

Ah this makes it clearer what you wanted. This is actually not that hard to do at all, I just need to change the lexer for the other thing I was talking about.

Would it be enough for you if I just made a function that returns all the variables that are used in a given expression, which you can use to compare against an array of variables that will be in the scope later?

am-kantox commented 7 years ago

Sure, as you want, I appreciate it, thanks!

narrowtux commented 6 years ago

works with https://github.com/narrowtux/abacus/commit/577e722ff0da7c43743d79cb7d9fce4aeeeb083e