Thread overview
How to use a non-static objects in string `mixin`?
Aug 27, 2022
hype_editor
Aug 27, 2022
Paul Backus
Aug 29, 2022
Dukc
August 27, 2022

I need to use function eval sometimes, but compiler throws an error: Error: variable firstOperand cannot be read at compile time.

import std.array;
import std.format;

public class BinaryOperatorExpression
{
	private
	{
		string operator;
		Expression firstExpr;
		Expression secondExpr;
	}

	public final this(T)(string operator, T firstExpr, T secondExpr)
	{
		this.operator = operator;
		this.firstExpr = firstExpr;
		this.secondExpr = secondExpr;
	}

	override public double eval()
	{
		double firstOperand = firstExpr.eval();
		double secondOperand = secondExpr.eval();

		return mixin(
			format("%d %s %d", firstOperand, operator, secondOperand)
		);
	}
}

Type T exactly has eval returning double'. How can I make firstOperandandsecondOperand` static?

August 27, 2022

On Saturday, 27 August 2022 at 13:20:13 UTC, hype_editor wrote:

>

I need to use function eval sometimes, but compiler throws an error: Error: variable firstOperand cannot be read at compile time.

	override public double eval()
	{
		double firstOperand = firstExpr.eval();
		double secondOperand = secondExpr.eval();

		return mixin(
			format("%d %s %d", firstOperand, operator, secondOperand)
		);
	}

mixin is not the right tool to use here. Try rewriting the code to use a switch statement or a series of if-else statements instead.

August 29, 2022

On Saturday, 27 August 2022 at 13:20:13 UTC, hype_editor wrote:

>

I need to use function eval sometimes, but compiler throws an error: Error: variable firstOperand cannot be read at compile time.

You're probably misunderstanding mixin. It does not work like an eval function at Lisp or
JavaScript or such. Instead, it evaluates it's contents at compile time, meaning that you can only use compile-time data in it, enum variables and template arguments for example.

Because the operator is not known at compile time, this means you need something else. Switch statement Paul Backus suggested is one option. You could alternatively try an associative array that maps the operators to the respective functions, something like (untested):

enum opMap =
[ "+": (double a, double b) => a+b,
  "-": (double a, double b) => a-b,
  //...
];

//in the eval function
return opMap[operator](firstOperand, secondOperand);