CompiledFunction
using CLanguage.Syntax;
using CLanguage.Types;
using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.CompilerServices;
namespace CLanguage.Interpreter
{
public class CompiledFunction : BaseFunction
{
[System.Runtime.CompilerServices.Nullable]
[field: System.Runtime.CompilerServices.Nullable]
public Block Body {
[return: System.Runtime.CompilerServices.Nullable]
get;
}
public List<CompiledVariable> LocalVariables { get; }
public List<Instruction> Instructions { get; }
public string Assembler {
get {
StringWriter stringWriter = new StringWriter();
for (int i = 0; i < Instructions.Count; i++) {
stringWriter.WriteLine("{0}: {1}", i, Instructions[i]);
}
return stringWriter.ToString();
}
}
public CompiledFunction(string name, CFunctionType functionType, [System.Runtime.CompilerServices.Nullable] Block body)
{
base.Name = name;
base.FunctionType = functionType;
Body = body;
LocalVariables = new List<CompiledVariable>();
Instructions = new List<Instruction>();
}
public CompiledFunction(string name, string nameContext, CFunctionType functionType)
: this(name, functionType, null)
{
base.NameContext = nameContext;
}
public override string ToString()
{
return base.Name;
}
public override void Init(CInterpreter state)
{
CompiledVariable compiledVariable = (LocalVariables.Count == 0) ? null : LocalVariables[LocalVariables.Count - 1];
if (compiledVariable != null)
state.SP += compiledVariable.Offset + compiledVariable.VariableType.NumValues;
}
public override void Step(CInterpreter state, ExecutionFrame frame)
{
int num = frame.IP;
bool flag = false;
Value value = default(Value);
Value value2 = default(Value);
while (!flag && num < Instructions.Count && state.RemainingTime > 0) {
Instruction instruction = Instructions[num];
switch (instruction.Op) {
case OpCode.Dup:
state.Stack[state.SP] = state.Stack[state.SP - 1];
state.SP++;
num++;
break;
case OpCode.Pop:
state.SP--;
num++;
break;
case OpCode.Jump:
if (instruction.Label == null)
throw new InvalidOperationException("Jump label not set");
num = instruction.Label.Index;
break;
case OpCode.BranchIfFalse:
value = state.Stack[state.SP - 1];
state.SP--;
if (value.UInt8Value == 0) {
if (instruction.Label == null)
throw new InvalidOperationException("BranchIfFalse label not set");
num = instruction.Label.Index;
} else
num++;
break;
case OpCode.Call:
value = state.Stack[state.SP - 1];
state.SP--;
num++;
state.Call(value);
flag = true;
break;
case OpCode.Return:
state.Return();
flag = true;
break;
case OpCode.LoadConstant:
state.Stack[state.SP] = instruction.X;
state.SP++;
num++;
break;
case OpCode.LoadFramePointer:
state.Stack[state.SP] = frame.FP;
state.SP++;
num++;
break;
case OpCode.LoadPointer:
value = state.Stack[state.SP - 1];
state.Stack[state.SP - 1] = state.Stack[value.PointerValue];
num++;
break;
case OpCode.StorePointer:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[value.PointerValue] = value2;
state.SP -= 2;
num++;
break;
case OpCode.OffsetPointer:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2].PointerValue = value.PointerValue + value2.Int32Value;
state.SP--;
num++;
break;
case OpCode.LoadGlobal:
state.Stack[state.SP] = state.Stack[instruction.X.Int32Value];
state.SP++;
num++;
break;
case OpCode.StoreGlobal:
state.Stack[instruction.X.Int32Value] = state.Stack[state.SP - 1];
state.SP--;
num++;
break;
case OpCode.LoadArg:
state.Stack[state.SP] = state.Stack[frame.FP + instruction.X.Int32Value];
state.SP++;
num++;
break;
case OpCode.StoreArg:
state.Stack[frame.FP + instruction.X.Int32Value] = state.Stack[state.SP - 1];
state.SP--;
num++;
break;
case OpCode.LoadLocal:
state.Stack[state.SP] = state.Stack[frame.FP + instruction.X.Int32Value];
state.SP++;
num++;
break;
case OpCode.StoreLocal:
state.Stack[frame.FP + instruction.X.Int32Value] = state.Stack[state.SP - 1];
state.SP--;
num++;
break;
case OpCode.AddInt8:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = (sbyte)value + (sbyte)value2;
state.SP--;
num++;
break;
case OpCode.AddUInt8:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = (byte)value + (byte)value2;
state.SP--;
num++;
break;
case OpCode.AddInt16:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = (short)value + (short)value2;
state.SP--;
num++;
break;
case OpCode.AddUInt16:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = (ushort)value + (ushort)value2;
state.SP--;
num++;
break;
case OpCode.AddInt32:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = (int)value + (int)value2;
state.SP--;
num++;
break;
case OpCode.AddUInt32:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = (uint)value + (uint)value2;
state.SP--;
num++;
break;
case OpCode.AddInt64:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = (long)value + (long)value2;
state.SP--;
num++;
break;
case OpCode.AddUInt64:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = (ulong)value + (ulong)value2;
state.SP--;
num++;
break;
case OpCode.AddFloat32:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = (float)value + (float)value2;
state.SP--;
num++;
break;
case OpCode.AddFloat64:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = (double)value + (double)value2;
state.SP--;
num++;
break;
case OpCode.SubtractInt8:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = (sbyte)value - (sbyte)value2;
state.SP--;
num++;
break;
case OpCode.SubtractUInt8:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = (byte)value - (byte)value2;
state.SP--;
num++;
break;
case OpCode.SubtractInt16:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = (short)value - (short)value2;
state.SP--;
num++;
break;
case OpCode.SubtractUInt16:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = (ushort)value - (ushort)value2;
state.SP--;
num++;
break;
case OpCode.SubtractInt32:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = (int)value - (int)value2;
state.SP--;
num++;
break;
case OpCode.SubtractUInt32:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = (uint)value - (uint)value2;
state.SP--;
num++;
break;
case OpCode.SubtractInt64:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = (long)value + (long)value2;
state.SP--;
num++;
break;
case OpCode.SubtractUInt64:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = (ulong)value + (ulong)value2;
state.SP--;
num++;
break;
case OpCode.SubtractFloat32:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = (float)value - (float)value2;
state.SP--;
num++;
break;
case OpCode.SubtractFloat64:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = (double)value - (double)value2;
state.SP--;
num++;
break;
case OpCode.MultiplyInt8:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = (sbyte)value * (sbyte)value2;
state.SP--;
num++;
break;
case OpCode.MultiplyUInt8:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = (byte)value * (byte)value2;
state.SP--;
num++;
break;
case OpCode.MultiplyInt16:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = (short)value * (short)value2;
state.SP--;
num++;
break;
case OpCode.MultiplyUInt16:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = (ushort)value * (ushort)value2;
state.SP--;
num++;
break;
case OpCode.MultiplyInt32:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = (int)value * (int)value2;
state.SP--;
num++;
break;
case OpCode.MultiplyUInt32:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = (uint)value * (uint)value2;
state.SP--;
num++;
break;
case OpCode.MultiplyFloat32:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = (float)value * (float)value2;
state.SP--;
num++;
break;
case OpCode.MultiplyFloat64:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = (double)value * (double)value2;
state.SP--;
num++;
break;
case OpCode.DivideInt8:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = (sbyte)value / (sbyte)value2;
state.SP--;
num++;
break;
case OpCode.DivideUInt8:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = (int)(byte)value / (int)(byte)value2;
state.SP--;
num++;
break;
case OpCode.DivideInt16:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = (short)value / (short)value2;
state.SP--;
num++;
break;
case OpCode.DivideUInt16:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = (int)(ushort)value / (int)(ushort)value2;
state.SP--;
num++;
break;
case OpCode.DivideInt32:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = (int)value / (int)value2;
state.SP--;
num++;
break;
case OpCode.DivideUInt32:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = (uint)value / (uint)value2;
state.SP--;
num++;
break;
case OpCode.DivideFloat32:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = (float)value / (float)value2;
state.SP--;
num++;
break;
case OpCode.DivideFloat64:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = (double)value / (double)value2;
state.SP--;
num++;
break;
case OpCode.ShiftLeftInt8:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = (sbyte)value << (int)(sbyte)value2;
state.SP--;
num++;
break;
case OpCode.ShiftLeftUInt8:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = (byte)value << (int)(byte)value2;
state.SP--;
num++;
break;
case OpCode.ShiftLeftInt16:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = (short)value << (int)(short)value2;
state.SP--;
num++;
break;
case OpCode.ShiftLeftUInt16:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = (ushort)value << (int)(ushort)value2;
state.SP--;
num++;
break;
case OpCode.ShiftLeftInt32:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = (int)value << (int)value2;
state.SP--;
num++;
break;
case OpCode.ShiftLeftUInt32:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = (uint)value << (int)value2;
state.SP--;
num++;
break;
case OpCode.ShiftLeftFloat32:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = (int)(float)value << (int)(float)value2;
state.SP--;
num++;
break;
case OpCode.ShiftLeftFloat64:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = (long)(double)value << (int)(double)value2;
state.SP--;
num++;
break;
case OpCode.ShiftRightInt8:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = (sbyte)value >> (int)(sbyte)value2;
state.SP--;
num++;
break;
case OpCode.ShiftRightUInt8:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = (byte)value >> (int)(byte)value2;
state.SP--;
num++;
break;
case OpCode.ShiftRightInt16:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = (short)value >> (int)(short)value2;
state.SP--;
num++;
break;
case OpCode.ShiftRightUInt16:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = (ushort)value >> (int)(ushort)value2;
state.SP--;
num++;
break;
case OpCode.ShiftRightInt32:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = (int)value >> (int)value2;
state.SP--;
num++;
break;
case OpCode.ShiftRightUInt32:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = (uint)value >> (int)value2;
state.SP--;
num++;
break;
case OpCode.ShiftRightFloat32:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = (int)(float)value >> (int)(float)value2;
state.SP--;
num++;
break;
case OpCode.ShiftRightFloat64:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = (long)(double)value >> (int)(double)value2;
state.SP--;
num++;
break;
case OpCode.ModuloInt16:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = (short)value % (short)value2;
state.SP--;
num++;
break;
case OpCode.ModuloUInt16:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = (int)(ushort)value % (int)(ushort)value2;
state.SP--;
num++;
break;
case OpCode.ModuloInt32:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = (int)value % (int)value2;
state.SP--;
num++;
break;
case OpCode.ModuloUInt32:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = (uint)value % (uint)value2;
state.SP--;
num++;
break;
case OpCode.ModuloFloat32:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = (float)value % (float)value2;
state.SP--;
num++;
break;
case OpCode.ModuloFloat64:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = (double)value % (double)value2;
state.SP--;
num++;
break;
case OpCode.BinaryAndInt8:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = ((sbyte)value & (sbyte)value2);
state.SP--;
num++;
break;
case OpCode.BinaryAndUInt8:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = ((byte)value & (byte)value2);
state.SP--;
num++;
break;
case OpCode.BinaryAndInt16:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = ((short)value & (short)value2);
state.SP--;
num++;
break;
case OpCode.BinaryAndUInt16:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = ((ushort)value & (ushort)value2);
state.SP--;
num++;
break;
case OpCode.BinaryAndInt32:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = ((int)value & (int)value2);
state.SP--;
num++;
break;
case OpCode.BinaryAndUInt32:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = ((uint)value & (uint)value2);
state.SP--;
num++;
break;
case OpCode.BinaryAndInt64:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = ((long)value & (long)value2);
state.SP--;
num++;
break;
case OpCode.BinaryAndUInt64:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = ((ulong)value & (ulong)value2);
state.SP--;
num++;
break;
case OpCode.BinaryAndFloat32:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = ((long)(float)value & (long)(float)value2);
state.SP--;
num++;
break;
case OpCode.BinaryAndFloat64:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = ((long)(double)value & (long)(double)value2);
state.SP--;
num++;
break;
case OpCode.BinaryOrInt8:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = ((sbyte)value | (sbyte)value2);
state.SP--;
num++;
break;
case OpCode.BinaryOrUInt8:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = ((byte)value | (byte)value2);
state.SP--;
num++;
break;
case OpCode.BinaryOrInt16:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = ((short)value | (short)value2);
state.SP--;
num++;
break;
case OpCode.BinaryOrUInt16:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = ((ushort)value | (ushort)value2);
state.SP--;
num++;
break;
case OpCode.BinaryOrInt32:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = ((int)value | (int)value2);
state.SP--;
num++;
break;
case OpCode.BinaryOrUInt32:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = ((uint)value | (uint)value2);
state.SP--;
num++;
break;
case OpCode.BinaryOrInt64:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = ((long)value | (long)value2);
state.SP--;
num++;
break;
case OpCode.BinaryOrUInt64:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = ((ulong)value | (ulong)value2);
state.SP--;
num++;
break;
case OpCode.BinaryOrFloat32:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = ((long)(float)value | (long)(float)value2);
state.SP--;
num++;
break;
case OpCode.BinaryOrFloat64:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = ((long)(double)value | (long)(double)value2);
state.SP--;
num++;
break;
case OpCode.BinaryXorInt8:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = ((sbyte)value ^ (sbyte)value2);
state.SP--;
num++;
break;
case OpCode.BinaryXorUInt8:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = ((byte)value ^ (byte)value2);
state.SP--;
num++;
break;
case OpCode.BinaryXorInt16:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = ((short)value ^ (short)value2);
state.SP--;
num++;
break;
case OpCode.BinaryXorUInt16:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = ((ushort)value ^ (ushort)value2);
state.SP--;
num++;
break;
case OpCode.BinaryXorInt32:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = ((int)value ^ (int)value2);
state.SP--;
num++;
break;
case OpCode.BinaryXorUInt32:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = ((uint)value ^ (uint)value2);
state.SP--;
num++;
break;
case OpCode.BinaryXorInt64:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = ((long)value ^ (long)value2);
state.SP--;
num++;
break;
case OpCode.BinaryXorUInt64:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = ((ulong)value ^ (ulong)value2);
state.SP--;
num++;
break;
case OpCode.BinaryXorFloat32:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = ((long)(float)value ^ (long)(float)value2);
state.SP--;
num++;
break;
case OpCode.BinaryXorFloat64:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = ((long)(double)value ^ (long)(double)value2);
state.SP--;
num++;
break;
case OpCode.EqualToInt16:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = (((short)value == (short)value2) ? 1 : 0);
state.SP--;
num++;
break;
case OpCode.EqualToUInt16:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = (((ushort)value == (ushort)value2) ? 1 : 0);
state.SP--;
num++;
break;
case OpCode.EqualToInt32:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = (((int)value == (int)value2) ? 1 : 0);
state.SP--;
num++;
break;
case OpCode.EqualToUInt32:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = (((uint)value == (uint)value2) ? 1 : 0);
state.SP--;
num++;
break;
case OpCode.EqualToFloat32:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = (((float)value == (float)value2) ? 1 : 0);
state.SP--;
num++;
break;
case OpCode.EqualToFloat64:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = (((double)value == (double)value2) ? 1 : 0);
state.SP--;
num++;
break;
case OpCode.LessThanInt16:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = (((short)value < (short)value2) ? 1 : 0);
state.SP--;
num++;
break;
case OpCode.LessThanUInt16:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = (((ushort)value < (ushort)value2) ? 1 : 0);
state.SP--;
num++;
break;
case OpCode.LessThanInt32:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = (((int)value < (int)value2) ? 1 : 0);
state.SP--;
num++;
break;
case OpCode.LessThanUInt32:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = (((uint)value < (uint)value2) ? 1 : 0);
state.SP--;
num++;
break;
case OpCode.LessThanFloat32:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = (((float)value < (float)value2) ? 1 : 0);
state.SP--;
num++;
break;
case OpCode.LessThanFloat64:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = (((double)value < (double)value2) ? 1 : 0);
state.SP--;
num++;
break;
case OpCode.GreaterThanInt16:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = (((short)value > (short)value2) ? 1 : 0);
state.SP--;
num++;
break;
case OpCode.GreaterThanUInt16:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = (((ushort)value > (ushort)value2) ? 1 : 0);
state.SP--;
num++;
break;
case OpCode.GreaterThanInt32:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = (((int)value > (int)value2) ? 1 : 0);
state.SP--;
num++;
break;
case OpCode.GreaterThanUInt32:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = (((uint)value > (uint)value2) ? 1 : 0);
state.SP--;
num++;
break;
case OpCode.GreaterThanFloat32:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = (((float)value > (float)value2) ? 1 : 0);
state.SP--;
num++;
break;
case OpCode.GreaterThanFloat64:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = (((double)value > (double)value2) ? 1 : 0);
state.SP--;
num++;
break;
case OpCode.NotInt8:
value = state.Stack[state.SP - 1];
state.Stack[state.SP - 1] = (((sbyte)value == 0) ? 1 : 0);
num++;
break;
case OpCode.NotUInt8:
value = state.Stack[state.SP - 1];
state.Stack[state.SP - 1] = (((byte)value == 0) ? 1 : 0);
num++;
break;
case OpCode.NotInt16:
value = state.Stack[state.SP - 1];
state.Stack[state.SP - 1] = (((short)value == 0) ? 1 : 0);
num++;
break;
case OpCode.NotUInt16:
value = state.Stack[state.SP - 1];
state.Stack[state.SP - 1] = (((ushort)value == 0) ? 1 : 0);
num++;
break;
case OpCode.NotInt32:
value = state.Stack[state.SP - 1];
state.Stack[state.SP - 1] = (((int)value == 0) ? 1 : 0);
num++;
break;
case OpCode.NotUInt32:
value = state.Stack[state.SP - 1];
state.Stack[state.SP - 1] = (((uint)value == 0) ? 1 : 0);
num++;
break;
case OpCode.NotInt64:
value = state.Stack[state.SP - 1];
state.Stack[state.SP - 1] = (((long)value == 0) ? 1 : 0);
num++;
break;
case OpCode.NotUInt64:
value = state.Stack[state.SP - 1];
state.Stack[state.SP - 1] = (((ulong)value == 0) ? 1 : 0);
num++;
break;
case OpCode.NotFloat32:
value = state.Stack[state.SP - 1];
state.Stack[state.SP - 1] = (((float)value == 0) ? 1 : 0);
num++;
break;
case OpCode.NotFloat64:
value = state.Stack[state.SP - 1];
state.Stack[state.SP - 1] = (((double)value == 0) ? 1 : 0);
num++;
break;
case OpCode.BinaryNotInt8:
value = state.Stack[state.SP - 1];
state.Stack[state.SP - 1] = ~(sbyte)value;
num++;
break;
case OpCode.BinaryNotUInt8:
value = state.Stack[state.SP - 1];
state.Stack[state.SP - 1] = ~(byte)value;
num++;
break;
case OpCode.BinaryNotInt16:
value = state.Stack[state.SP - 1];
state.Stack[state.SP - 1] = ~(short)value;
num++;
break;
case OpCode.BinaryNotUInt16:
value = state.Stack[state.SP - 1];
state.Stack[state.SP - 1] = ~(ushort)value;
num++;
break;
case OpCode.BinaryNotInt32:
value = state.Stack[state.SP - 1];
state.Stack[state.SP - 1] = ~(int)value;
num++;
break;
case OpCode.BinaryNotUInt32:
value = state.Stack[state.SP - 1];
state.Stack[state.SP - 1] = ~(uint)value;
num++;
break;
case OpCode.BinaryNotInt64:
value = state.Stack[state.SP - 1];
state.Stack[state.SP - 1] = ~(long)value;
num++;
break;
case OpCode.BinaryNotUInt64:
value = state.Stack[state.SP - 1];
state.Stack[state.SP - 1] = ~(ulong)value;
num++;
break;
case OpCode.BinaryNotFloat32:
value = state.Stack[state.SP - 1];
state.Stack[state.SP - 1] = ~(int)(float)value;
num++;
break;
case OpCode.BinaryNotFloat64:
value = state.Stack[state.SP - 1];
state.Stack[state.SP - 1] = ~(int)(double)value;
num++;
break;
case OpCode.NegateInt8:
value = state.Stack[state.SP - 1];
state.Stack[state.SP - 1] = -(sbyte)value;
num++;
break;
case OpCode.NegateUInt8:
value = state.Stack[state.SP - 1];
state.Stack[state.SP - 1] = -(byte)value;
num++;
break;
case OpCode.NegateInt16:
value = state.Stack[state.SP - 1];
state.Stack[state.SP - 1] = -(short)value;
num++;
break;
case OpCode.NegateUInt16:
value = state.Stack[state.SP - 1];
state.Stack[state.SP - 1] = -(ushort)value;
num++;
break;
case OpCode.NegateInt32:
value = state.Stack[state.SP - 1];
state.Stack[state.SP - 1] = -(int)value;
num++;
break;
case OpCode.NegateUInt32:
value = state.Stack[state.SP - 1];
state.Stack[state.SP - 1] = 0 - (uint)value;
num++;
break;
case OpCode.NegateInt64:
value = state.Stack[state.SP - 1];
state.Stack[state.SP - 1] = -(long)value;
num++;
break;
case OpCode.NegateUInt64:
value = state.Stack[state.SP - 1];
state.Stack[state.SP - 1] = (ulong)(-(long)value);
num++;
break;
case OpCode.NegateFloat32:
value = state.Stack[state.SP - 1];
state.Stack[state.SP - 1] = 0 - (float)value;
num++;
break;
case OpCode.NegateFloat64:
value = state.Stack[state.SP - 1];
state.Stack[state.SP - 1] = 0 - (double)value;
num++;
break;
case OpCode.LogicalAnd:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = ((value.Int32Value != 0 && value2.Int32Value != 0) ? 1 : 0);
state.SP--;
num++;
break;
case OpCode.LogicalOr:
value = state.Stack[state.SP - 2];
value2 = state.Stack[state.SP - 1];
state.Stack[state.SP - 2] = ((value.Int32Value != 0 || value2.Int32Value != 0) ? 1 : 0);
state.SP--;
num++;
break;
default:
value = state.Stack[state.SP - 1];
state.Stack[state.SP - 1] = Convert(value, instruction.Op);
num++;
break;
}
state.RemainingTime -= state.CpuSpeed;
}
frame.IP = num;
if (num >= Instructions.Count)
throw new ExecutionException("Function '" + base.Name + "' never returned.");
}
private Value Convert(Value x, OpCode op)
{
switch (op) {
case OpCode.ConvertInt8Int8:
return (sbyte)x;
case OpCode.ConvertInt8UInt8:
return (byte)(sbyte)x;
case OpCode.ConvertInt8Int16:
return (short)(sbyte)x;
case OpCode.ConvertInt8UInt16:
return (ushort)(sbyte)x;
case OpCode.ConvertInt8Int32:
return (int)(sbyte)x;
case OpCode.ConvertInt8UInt32:
return (uint)(sbyte)x;
case OpCode.ConvertInt8Int64:
return (long)(sbyte)x;
case OpCode.ConvertInt8UInt64:
return (ulong)(sbyte)x;
case OpCode.ConvertInt8Float32:
return (float)(sbyte)x;
case OpCode.ConvertInt8Float64:
return (double)(sbyte)x;
case OpCode.ConvertUInt8Int8:
return (sbyte)(byte)x;
case OpCode.ConvertUInt8UInt8:
return (byte)x;
case OpCode.ConvertUInt8Int16:
return (short)(byte)x;
case OpCode.ConvertUInt8UInt16:
return (ushort)(byte)x;
case OpCode.ConvertUInt8Int32:
return (int)(byte)x;
case OpCode.ConvertUInt8UInt32:
return (uint)(byte)x;
case OpCode.ConvertUInt8Int64:
return (long)(byte)x;
case OpCode.ConvertUInt8UInt64:
return (ulong)(byte)x;
case OpCode.ConvertUInt8Float32:
return (float)(int)(byte)x;
case OpCode.ConvertUInt8Float64:
return (double)(int)(byte)x;
case OpCode.ConvertInt16Int8:
return (sbyte)(short)x;
case OpCode.ConvertInt16UInt8:
return (byte)(short)x;
case OpCode.ConvertInt16Int16:
return (short)x;
case OpCode.ConvertInt16UInt16:
return (ushort)(short)x;
case OpCode.ConvertInt16Int32:
return (int)(short)x;
case OpCode.ConvertInt16UInt32:
return (uint)(short)x;
case OpCode.ConvertInt16Int64:
return (long)(short)x;
case OpCode.ConvertInt16UInt64:
return (ulong)(short)x;
case OpCode.ConvertInt16Float32:
return (float)(short)x;
case OpCode.ConvertInt16Float64:
return (double)(short)x;
case OpCode.ConvertUInt16Int8:
return (sbyte)(ushort)x;
case OpCode.ConvertUInt16UInt8:
return (byte)(ushort)x;
case OpCode.ConvertUInt16Int16:
return (short)(ushort)x;
case OpCode.ConvertUInt16UInt16:
return (ushort)x;
case OpCode.ConvertUInt16Int32:
return (int)(ushort)x;
case OpCode.ConvertUInt16UInt32:
return (uint)(ushort)x;
case OpCode.ConvertUInt16Int64:
return (long)(ushort)x;
case OpCode.ConvertUInt16UInt64:
return (ulong)(ushort)x;
case OpCode.ConvertUInt16Float32:
return (float)(int)(ushort)x;
case OpCode.ConvertUInt16Float64:
return (double)(int)(ushort)x;
case OpCode.ConvertInt32Int8:
return (sbyte)(int)x;
case OpCode.ConvertInt32UInt8:
return (byte)(int)x;
case OpCode.ConvertInt32Int16:
return (short)(int)x;
case OpCode.ConvertInt32UInt16:
return (ushort)(int)x;
case OpCode.ConvertInt32Int32:
return (int)x;
case OpCode.ConvertInt32UInt32:
return (uint)(int)x;
case OpCode.ConvertInt32Int64:
return (long)(int)x;
case OpCode.ConvertInt32UInt64:
return (ulong)(int)x;
case OpCode.ConvertInt32Float32:
return (float)(int)x;
case OpCode.ConvertInt32Float64:
return (double)(int)x;
case OpCode.ConvertUInt32Int8:
return (sbyte)(uint)x;
case OpCode.ConvertUInt32UInt8:
return (byte)(uint)x;
case OpCode.ConvertUInt32Int16:
return (short)(uint)x;
case OpCode.ConvertUInt32UInt16:
return (ushort)(uint)x;
case OpCode.ConvertUInt32Int32:
return (int)(uint)x;
case OpCode.ConvertUInt32UInt32:
return (uint)x;
case OpCode.ConvertUInt32Int64:
return (long)(uint)x;
case OpCode.ConvertUInt32UInt64:
return (ulong)(uint)x;
case OpCode.ConvertUInt32Float32:
return (float)(double)(uint)x;
case OpCode.ConvertUInt32Float64:
return (double)(uint)x;
case OpCode.ConvertInt64Int8:
return (sbyte)(long)x;
case OpCode.ConvertInt64UInt8:
return (byte)(long)x;
case OpCode.ConvertInt64Int16:
return (short)(long)x;
case OpCode.ConvertInt64UInt16:
return (ushort)(long)x;
case OpCode.ConvertInt64Int32:
return (int)(long)x;
case OpCode.ConvertInt64UInt32:
return (uint)(long)x;
case OpCode.ConvertInt64Int64:
return (long)x;
case OpCode.ConvertInt64UInt64:
return (ulong)(long)x;
case OpCode.ConvertInt64Float32:
return (float)(long)x;
case OpCode.ConvertInt64Float64:
return (double)(long)x;
case OpCode.ConvertUInt64Int8:
return (sbyte)(ulong)x;
case OpCode.ConvertUInt64UInt8:
return (byte)(ulong)x;
case OpCode.ConvertUInt64Int16:
return (short)(ulong)x;
case OpCode.ConvertUInt64UInt16:
return (ushort)(ulong)x;
case OpCode.ConvertUInt64Int32:
return (int)(ulong)x;
case OpCode.ConvertUInt64UInt32:
return (uint)(ulong)x;
case OpCode.ConvertUInt64Int64:
return (long)(ulong)x;
case OpCode.ConvertUInt64UInt64:
return (ulong)x;
case OpCode.ConvertUInt64Float32:
return (float)(double)(ulong)x;
case OpCode.ConvertUInt64Float64:
return (double)(ulong)x;
case OpCode.ConvertFloat32Int8:
return (sbyte)(float)x;
case OpCode.ConvertFloat32UInt8:
return (byte)(float)x;
case OpCode.ConvertFloat32Int16:
return (short)(float)x;
case OpCode.ConvertFloat32UInt16:
return (ushort)(float)x;
case OpCode.ConvertFloat32Int32:
return (int)(float)x;
case OpCode.ConvertFloat32UInt32:
return (uint)(float)x;
case OpCode.ConvertFloat32Int64:
return (long)(float)x;
case OpCode.ConvertFloat32UInt64:
return (ulong)(float)x;
case OpCode.ConvertFloat32Float32:
return (float)x;
case OpCode.ConvertFloat32Float64:
return (double)(float)x;
case OpCode.ConvertFloat64Int8:
return (sbyte)(double)x;
case OpCode.ConvertFloat64UInt8:
return (byte)(double)x;
case OpCode.ConvertFloat64Int16:
return (short)(double)x;
case OpCode.ConvertFloat64UInt16:
return (ushort)(double)x;
case OpCode.ConvertFloat64Int32:
return (int)(double)x;
case OpCode.ConvertFloat64UInt32:
return (uint)(double)x;
case OpCode.ConvertFloat64Int64:
return (long)(double)x;
case OpCode.ConvertFloat64UInt64:
return (ulong)(double)x;
case OpCode.ConvertFloat64Float32:
return (float)(double)x;
case OpCode.ConvertFloat64Float64:
return (double)x;
default:
throw new NotSupportedException($"""{op}""");
}
}
}
}