﻿using Nitra.Model;
using Nitra.Typing;

using Nemerle;
using Nemerle.Collections;
using Nemerle.Text;
using Nemerle.Utility;

using System;
using System.Text;

namespace Nitra.Compiler.PatternMatching
{
  internal variant Decision[T]
  {
    | Failure
    | Success { Value : T }
    | IfEq
      {
        Access : Access;
        Con    : ParseTreeCtor;
        True   : Decision[T];
        False  : Decision[T];
      }
    | Variable
      {
        Name         : Identifier;
        Access       : Access;
        Continuation : Decision[T];
      }
 
    public static AppendDecision(this buffer : StringBuilder, tab : int, decision : Decision[T]) : StringBuilder
    {
      match (decision)
      {
        | Failure        => buffer.Append(' ', tab).Append("FAIL")
        | Success(value) => buffer.Append(' ', tab).Append("return ").Append(value)
        | IfEq(access, con, t, f) =>
          buffer.Append(' ', tab).Append("If ").AppendAccess(access).Append(" is ").AppendCtor(con).AppendLine()
            .AppendDecision(tab + 2, t).AppendLine()
            .Append(' ', tab).Append("Else").AppendLine()
            .AppendDecision(tab + 2, f)

        | Variable(name, access, continuation) =>
          buffer.Append(' ', tab).Append("var ").Append(name.Value).Append(" = ").AppendAccess(access).AppendLine()
            .AppendDecision(tab, continuation)
      }
    }
 
    public override ToString() : string
    {
      StringBuilder().AppendDecision(0, this).ToString()
    }
  }
}
