// Copyright Epic Games, Inc. All Rights Reserved.
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using EpicGames.BuildGraph.Expressions;
using EpicGames.Core;
using Microsoft.Extensions.Logging;
namespace EpicGames.BuildGraph
{
///
/// Exception thrown by the runtime
///
public sealed class BgBytecodeException : Exception
{
///
/// Source file that the error was thrown from
///
public string SourceFile { get; }
///
/// Line number that threw the exception
///
public int SourceLine { get; }
///
/// Message to display
///
public string Diagnostic { get; }
///
/// Constructor
///
///
///
///
public BgBytecodeException(string sourceFile, int sourceLine, string diagnostic)
{
SourceFile = sourceFile;
SourceLine = sourceLine;
Diagnostic = diagnostic;
}
///
public override string ToString() => $"{SourceFile}({SourceLine}): {Diagnostic}";
}
///
/// Interprets compiled buildgraph bytecode
///
public class BgInterpreter
{
enum BgArg
{
None,
Value,
ArgList,
Fragment,
Name,
Thunk,
StringLiteral,
VarIntSigned,
VarIntUnsigned,
}
readonly struct BgOpcodeInfo
{
readonly uint _data;
public BgOpcodeInfo(BgArg arg1) : this(1, arg1, BgArg.None, BgArg.None) { }
public BgOpcodeInfo(BgArg arg1, BgArg arg2) : this(2, arg1, arg2, BgArg.None) { }
public BgOpcodeInfo(BgArg arg1, BgArg arg2, BgArg arg3) : this(3, arg1, arg2, arg3) { }
private BgOpcodeInfo(int count, BgArg arg1, BgArg arg2, BgArg arg3)
{
_data = (uint)arg1 | ((uint)arg2 << 4) | ((uint)arg3 << 8) | ((uint)count << 12);
}
public int ArgCount => (int)((_data >> 12) & 0x7);
public BgArg Arg0 => GetArg(0);
public BgArg Arg1 => GetArg(1);
public BgArg Arg2 => GetArg(2);
public BgArg GetArg(int idx) => (BgArg)((_data >> (idx * 4)) & 0xf);
}
class Frame
{
public int Offset { get; set; }
public IReadOnlyList