PaesslerAG / gval

Expression evaluation in golang
BSD 3-Clause "New" or "Revised" License
731 stars 82 forks source link

How to define a language which allows to create varaiables? #62

Closed AllenDang closed 3 years ago

AllenDang commented 3 years ago

I intend to create a new language to accept following expressions:

a = 1 + 2
b = a * 0.1
a + b

The program will eval it line-by-line, so the ideal result will be:

  1. Found a new variable named 'a' and it's value is Evaluate("1+2"). Register "a" and it's value 3 to the parameter map which will be used to eval next line.
  2. Found a new variable named 'b' and it's value is Evaluate("a * 0.1", map[string]interface{}{"a":3}).
  3. Finally Evaluate("a + b", map[string]interface{}{"a": 3, "b":0.3}).

I'm trying to create a calculator notebook app which allows user to create new avarialbe and new functions.

I found gval.InfixEvalOperator maybe the right spot to look, but I'm stucked by getting the text value of a.

Here is the demo code

        gval.InfixEvalOperator("=", func(a, b gval.Evaluable) (gval.Evaluable, error) {
            return func(c context.Context, v interface{}) (interface{}, error) {
                // I should get a's text value as the variable name here.
                // and register global parameter map with a's text value to b's eval result.
                return b.EvalString(c, v) // This is is just let me know the value of b.
            }, nil
        }),

Any hint?

generikvault commented 3 years ago

gval is designd for interpreting expressions. It's not fitting for Interpreting instructions.

You can solve that in two ways: Building a Wrapper around gval or by modifiyng your language into an expression.

1:

type Wrapper struct{
  assignments []struct{variable string, expression Gval.Evaluable}
  expression Gval.Evaluable
}

Filling the values by parsing each line and the var name seperatly.

2:

${
a: 1 + 2
b:  a * 0.1
}
a + b

Write a prefix extension $. This extension parses two expresions enviroment and expression. On Evaluation it evaluates first the enviroment and parses the resulting value to the expression. The enviroment part is basicly a json object, so this part canbe handled by default.

AllenDang commented 3 years ago

@generikvault Thanks for the tips. I will check them out.