import { Value } from '../value.mts';
import { Q } from '../completion.mts';
import { Evaluate, type ValueEvaluator } from '../evaluator.mts';
import { TV } from '../static-semantics/all.mts';
import type { ParseNode } from '../parser/ParseNode.mts';
import { GetValue, ToString } from '#self';

/** https://tc39.es/ecma262/#sec-template-literals-runtime-semantics-evaluation */
//   TemplateLiteral : NoSubstitutionTemplate
//   SubstitutionTemplate : TemplateHead Expression TemplateSpans
//   TemplateSpans : TemplateTail
//   TemplateSpans : TemplateMiddleList TemplateTail
//   TemplateMiddleList : TemplateMiddle Expression
//   TemplateMiddleList : TemplateMiddleList TemplateMiddle Expression
//
// (implicit)
//   TemplateLiteral : SubstitutionTemplate
export function* Evaluate_TemplateLiteral({ TemplateSpanList, ExpressionList }: ParseNode.TemplateLiteral): ValueEvaluator {
  let str = '';
  for (let i = 0; i < TemplateSpanList.length - 1; i += 1) {
    const Expression = ExpressionList[i];
    const head = TV(TemplateSpanList[i]);
    // 2. Let subRef be the result of evaluating Expression.
    const subRef = Q(yield* Evaluate(Expression));
    // 3. Let sub be ? GetValue(subRef).
    const sub = Q(yield* GetValue(subRef));
    // 4. Let middle be ? ToString(sub).
    const middle = Q(yield* ToString(sub));
    str += head;
    str += middle.stringValue();
  }
  const tail = TV(TemplateSpanList[TemplateSpanList.length - 1]);
  return Value(str + tail);
}
