CompiledFunction
using CLanguage.Syntax;
using CLanguage.Types;
using System;
using System.Collections.Generic;
using System.IO;
namespace CLanguage.Interpreter
{
public class CompiledFunction : BaseFunction
{
public Block Body { get; set; }
public List<CompiledVariable> LocalVariables { get; set; }
public List<Instruction> Instructions { get; set; }
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, Block body = null)
{
base.Name = name;
base.FunctionType = functionType;
Body = body;
LocalVariables = new List<CompiledVariable>();
Instructions = new List<Instruction>();
}
public CompiledFunction(string name, string nameContext, CFunctionType functionType, Block body = null)
: this(name, functionType, body)
{
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 activeFrame = state.ActiveFrame;
int num = activeFrame.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:
num = instruction.Label.Index;
break;
case OpCode.BranchIfFalse:
value = state.Stack[state.SP - 1];
state.SP--;
num = ((value.Int32Value != 0) ? (num + 1) : instruction.Label.Index);
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] = activeFrame.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[activeFrame.FP + instruction.X.Int32Value];
state.SP++;
num++;
break;
case OpCode.StoreArg:
state.Stack[activeFrame.FP + instruction.X.Int32Value] = state.Stack[state.SP - 1];
state.SP--;
num++;
break;
case OpCode.LoadLocal:
state.Stack[state.SP] = state.Stack[activeFrame.FP + instruction.X.Int32Value];
state.SP++;
num++;
break;
case OpCode.StoreLocal:
state.Stack[activeFrame.FP + instruction.X.Int32Value] = state.Stack[state.SP - 1];
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.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.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.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.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.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.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.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.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.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.LogicalNot:
value = state.Stack[state.SP - 1];
state.Stack[state.SP - 1] = ((value.Int32Value == 0) ? 1 : 0);
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:
throw new NotImplementedException(instruction.Op + " has not been implemented yet.");
}
state.RemainingTime -= state.CpuSpeed;
}
activeFrame.IP = num;
if (num >= Instructions.Count)
throw new ExecutionException("Function '" + base.Name + "' never returned.");
}
}
}