PaesslerAG/gval

How to define a language which allows to create varaiables?

AllenDang opened this issue · 2 comments

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?

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.

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