internal static string GetSourcesMd5(Instruction[] bytecode) { foreach (var instruction in bytecode) { if (instruction.Opcode == Instruction.Opcodes.VmSourcesMd5) { return((string)instruction.Arguments); } } Utils.Panic(); return(null); }
public static Instruction[] Assemble(List <Instruction> bytecode) { int length = 0; var labels = new Dictionary <string, int>(); foreach (var instruction in bytecode) { if (instruction.Opcode == Instruction.Opcodes.Label) { var label = (string)instruction.Arguments; if (labels.ContainsKey(label)) { Utils.Panic(); } labels[label] = length; } else { length++; } } var result = new Instruction[length]; var index = 0; foreach (var instruction in bytecode) { if (instruction.Opcode != Instruction.Opcodes.Label) { result[index] = instruction; index++; if (instruction.Opcode == Instruction.Opcodes.Fjump || instruction.Opcode == Instruction.Opcodes.Tjump || instruction.Opcode == Instruction.Opcodes.Jump || instruction.Opcode == Instruction.Opcodes.Block) { instruction.Arguments = labels[(string)instruction.Arguments]; } else if (instruction.Opcode == Instruction.Opcodes.Fn) { var args = (object[])instruction.Arguments; var label = (string)args[0]; instruction.Arguments = new int[] { labels [label], (int)args [1] }; } instruction.NumericOpcode = Utils.GetNumericOpcode(instruction.Opcode); } } return(result); }
public override bool Equals(object obj) { if (!(obj is Value)) { return(false); } var sv = (Value)obj; switch (this.Kind) { case Kinds.String: return(sv.Kind == Kinds.String && this.stringValue == sv.stringValue); case Kinds.Integer: return(sv.Kind == Kinds.Integer && this.integerValue == sv.integerValue); case Kinds.Null: return(sv.Kind == Kinds.Null); case Kinds.Double: return(sv.Kind == Kinds.Double && this.doubleValue == sv.doubleValue); case Kinds.Bool: return(sv.Kind == Kinds.Bool && this.boolValue == sv.boolValue); case Kinds.Array: return(sv.Kind == Kinds.Array && this.arrayValue == sv.arrayValue); case Kinds.Hash: return(sv.Kind == Kinds.Hash && this.hashValue == sv.hashValue); case Kinds.Callable: return(sv.Kind == Kinds.Callable && Equals(this.callableValue, sv.callableValue)); case Kinds.ReturnAddress: return(sv.Kind == Kinds.ReturnAddress && Equals(this.returnAddressValue, sv.returnAddressValue)); case Kinds.NamedBlock: return(sv.Kind == Kinds.NamedBlock && Equals(this.namedBlockValue, sv.namedBlockValue)); case Kinds.Struct: return(sv.Kind == Kinds.Struct && Equals(this.StructValue, sv.StructValue)); case Kinds.StructInstance: return(sv.Kind == Kinds.StructInstance && Equals(this.structInstanceValue, sv.structInstanceValue)); default: Utils.Panic(); throw new InvalidOperationException(); } }
public override int GetHashCode() { switch (this.Kind) { case Kinds.String: return(this.stringValue.GetHashCode()); case Kinds.Integer: return(this.integerValue.GetHashCode()); case Kinds.Null: return(0); case Kinds.Double: return(this.doubleValue.GetHashCode()); case Kinds.Bool: return(this.boolValue.GetHashCode()); case Kinds.Array: return(this.arrayValue.GetHashCode()); case Kinds.Hash: return(this.hashValue.GetHashCode()); case Kinds.Callable: return(this.callableValue.GetHashCode()); case Kinds.ReturnAddress: return(this.returnAddressValue.GetHashCode()); case Kinds.NamedBlock: return(this.namedBlockValue.GetHashCode()); case Kinds.Struct: return(this.StructValue.GetHashCode()); case Kinds.StructInstance: return(this.structInstanceValue.GetHashCode()); default: Utils.Panic(); throw new InvalidOperationException(); } }
static byte GetNumericOpcode(Instruction.Opcodes opcode) { switch (opcode) { case Instruction.Opcodes.Jump: return(0); case Instruction.Opcodes.Const: return(1); case Instruction.Opcodes.Prim0: return(2); case Instruction.Opcodes.Prim: return(3); case Instruction.Opcodes.Call: return(4); case Instruction.Opcodes.CallJ: return(5); case Instruction.Opcodes.Fjump: return(6); case Instruction.Opcodes.Lset: return(7); case Instruction.Opcodes.Pop: return(8); case Instruction.Opcodes.Lget: return(9); case Instruction.Opcodes.Fn: return(10); case Instruction.Opcodes.NewFrame: return(11); case Instruction.Opcodes.DropFrame: return(12); case Instruction.Opcodes.Args: return(13); case Instruction.Opcodes.Return: return(14); case Instruction.Opcodes.Block: return(15); case Instruction.Opcodes.PopBlock: return(16); case Instruction.Opcodes.BlockReturn: return(17); case Instruction.Opcodes.Context: return(18); case Instruction.Opcodes.Tjump: return(19); case Instruction.Opcodes.FileName: return(20); case Instruction.Opcodes.VmVersion: return(20); case Instruction.Opcodes.VmSourcesMd5: return(20); case Instruction.Opcodes.VmBytecodeMd5: return(20); case Instruction.Opcodes.Div: return(21); case Instruction.Opcodes.Mod: return(22); case Instruction.Opcodes.Neq: return(23); case Instruction.Opcodes.Lt: return(24); case Instruction.Opcodes.Add: return(25); case Instruction.Opcodes.Gref: return(26); case Instruction.Opcodes.Eq: return(27); case Instruction.Opcodes.Apush: return(28); case Instruction.Opcodes.GrefDot: return(29); case Instruction.Opcodes.Sub: return(30); case Instruction.Opcodes.Neg: return(31); case Instruction.Opcodes.Mul: return(32); case Instruction.Opcodes.Shl: return(33); case Instruction.Opcodes.Shr: return(34); case Instruction.Opcodes.Pow: return(35); case Instruction.Opcodes.Floor: return(36); case Instruction.Opcodes.Lte: return(37); case Instruction.Opcodes.Gt: return(38); case Instruction.Opcodes.Gte: return(39); case Instruction.Opcodes.Not: return(40); case Instruction.Opcodes.And: return(41); case Instruction.Opcodes.Ior: return(42); case Instruction.Opcodes.Xor: return(43); case Instruction.Opcodes.Keys: return(44); case Instruction.Opcodes.HasKey: return(45); case Instruction.Opcodes.Apop: return(46); case Instruction.Opcodes.SetIndexed: return(47); case Instruction.Opcodes.Len: return(48); case Instruction.Opcodes.IsString: return(49); case Instruction.Opcodes.IsHash: return(50); case Instruction.Opcodes.IsBool: return(51); case Instruction.Opcodes.IsArray: return(52); case Instruction.Opcodes.IsNumber: return(53); case Instruction.Opcodes.IsInteger: return(54); case Instruction.Opcodes.IsCallable: return(55); default: Utils.Panic(); return(0); } }