private void Expand(XILSInstr xilsi) { var preds = RemapPreds(xilsi.Preds); var expansion = Pattern.Expand(xilsi, preds); if (expansion == null) { ProcessDefault(xilsi); } else { foreach (XILSInstr xilsix in expansion) { Emit(xilsix); } if (xilsi.ResultTypes.Length > 0 && !TypeStack.Peek().Equals(xilsi.ResultTypes.Last())) { Emit( DefaultInstructionSet.Instance.Convert() .CreateStk(1, TypeStack.Peek(), xilsi.ResultTypes.Last())); } } }
private void CompileRepeat(GMLToken _tok) { VMLabel vMLabel = new VMLabel("End", VMB); VMLabel vMLabel2 = new VMLabel("Repeat", VMB); CompileExpression(_tok.Children[0]); eVM_Type eVM_Type = TypeStack.Pop(); if (eVM_Type != eVM_Type.eVMT_Int) { Emit(eVM_Instruction.eVMI_CONV, eVM_Type, eVM_Type.eVMT_Int); } Emit(eVM_Instruction.eVMI_DUP, eVM_Type.eVMT_Int); EmitI(eVM_Instruction.eVMI_PUSH, 0); Emit(eVM_Instruction.eVMI_SET_LE, eVM_Type.eVMT_Int, eVM_Type.eVMT_Int); Emit(eVM_Instruction.eVMI_BTRUE, vMLabel); LoopEnv.Push(vMLabel2); LoopEndEnv.Push(vMLabel); vMLabel2.Mark(VMB.Buffer.Position); CompileStatement(_tok.Children[1]); EmitI(eVM_Instruction.eVMI_PUSH, 1); Emit(eVM_Instruction.eVMI_SUB, eVM_Type.eVMT_Int, eVM_Type.eVMT_Int); Emit(eVM_Instruction.eVMI_DUP, eVM_Type.eVMT_Int); Emit(eVM_Instruction.eVMI_CONV, eVM_Type.eVMT_Int, eVM_Type.eVMT_Bool); Emit(eVM_Instruction.eVMI_BTRUE, vMLabel2); vMLabel.Mark(VMB.Buffer.Position); Emit(eVM_Instruction.eVMI_POPNULL, eVM_Type.eVMT_Int); LoopEnv.Pop(); LoopEndEnv.Pop(); }
private void HandleStoreVar(XILSInstr i) { int readPoint; Variable local = i.StaticOperand as Variable; if (DflowAnalyzer.IsReadAfterWrite(i.Index, out readPoint)) { var preds = RemapPreds(i.Preds); // keep expression on the stack, but bury it at the very bottom. for (int j = 1; j < _resultStack.Count; j++) { var resultTypes = TypeStack.Reverse().Skip(1).Concat(TypeStack.Skip(_resultStack.Count - 1)).ToArray(); Emit(DefaultInstructionSet.Instance.Dig(_resultStack.Count - 1).CreateStk( preds, TypeStack.Reverse().ToArray(), resultTypes)); preds = new InstructionDependency[0]; } _read2write[readPoint] = _resultStack[0]; } else if (local == null) { ProcessDefault(i); } else if (DflowAnalyzer.EliminableLocals.Contains(local.LocalIndex)) { Emit(DefaultInstructionSet.Instance.Pop().CreateStk(1, local.Type)); } else { ProcessDefault(i); } }
/// <summary> /// Emit code storing the value on the stack to memory /// </summary> /// <param name="name"></param> /// <param name="types"></param> public void Store(VariableName name, TypeStack <TEmit> types) { // Update the type tracker with the newly discovered type _types.Store(name, types.Peek); if (_cache.ContainsKey(name)) { var local = _cache[name]; // Convert to the correct type for this local var inType = types.Peek; ConvertType(inType, local.Type); types.Pop(inType); // Store in appropriate local _emitter.StoreLocal(local.Local); // Mark cache dirty _emitter.LoadConstant(true); _emitter.StoreLocal(_cacheDirty[name]); } else { // Immediately convert type to YololValue ConvertType(types.Peek, StackType.YololValue); types.Pop(types.Peek); // Write directly to backing store EmitStoreValue(name); } }
private void CompilePop(GMLToken _tok, eVM_Type _type) { switch (_tok.Token) { case eToken.eVariable: case eToken.eDot: if (_tok.Children.Count >= 2) { int num = 0; CompileExpression(_tok.Children[0]); if (TypeStack.Peek() != eVM_Type.eVMT_Int) { Emit(eVM_Instruction.eVMI_CONV, TypeStack.Pop(), eVM_Type.eVMT_Int); TypeStack.Push(eVM_Type.eVMT_Int); } if (_tok.Children[1].Children.Count > 0) { CompileExpression(_tok.Children[1].Children[0]); if (TypeStack.Peek() != eVM_Type.eVMT_Int) { Emit(eVM_Instruction.eVMI_CONV, TypeStack.Pop(), eVM_Type.eVMT_Int); TypeStack.Push(eVM_Type.eVMT_Int); } if (_tok.Children[1].Children.Count > 1) { EmitI(eVM_Instruction.eVMI_PUSH, 32000); Emit(eVM_Instruction.eVMI_MUL, eVM_Type.eVMT_Int, eVM_Type.eVMT_Int); CompileExpression(_tok.Children[1].Children[1]); if (TypeStack.Peek() != eVM_Type.eVMT_Int) { Emit(eVM_Instruction.eVMI_CONV, TypeStack.Pop(), eVM_Type.eVMT_Int); TypeStack.Push(eVM_Type.eVMT_Int); } Emit(eVM_Instruction.eVMI_ADD, eVM_Type.eVMT_Int, eVM_Type.eVMT_Int); TypeStack.Pop(); } TypeStack.Pop(); } else { num |= int.MinValue; } TypeStack.Pop(); EmitIVar(eVM_Instruction.eVMI_POP, _tok.Children[1].Id | num, _type); TypeStack.Push(eVM_Type.eVMT_Variable); } else { Error("Malformed variable reference", _tok); } break; case eToken.eConstant: Error("Unsure where these come from", _tok); break; } }
private void BinaryTypeCoercion(GMLToken _tok, int _parmNum) { eVM_Type eVM_Type = TypeStack.Peek(); switch (_tok.Children[1].Token) { case eToken.eNot: case eToken.eLess: case eToken.eLessEqual: case eToken.eEqual: case eToken.eNotEqual: case eToken.eGreaterEqual: case eToken.eGreater: case eToken.eBitNegate: break; case eToken.ePlus: case eToken.eMinus: case eToken.eTime: case eToken.eDivide: case eToken.eDiv: case eToken.eMod: if (eVM_Type == eVM_Type.eVMT_Bool) { TypeStack.Pop(); Emit(eVM_Instruction.eVMI_CONV, eVM_Type, eVM_Type.eVMT_Int); TypeStack.Push(eVM_Type.eVMT_Int); } break; case eToken.eAnd: case eToken.eOr: case eToken.eXor: if (eVM_Type != eVM_Type.eVMT_Bool) { TypeStack.Pop(); Emit(eVM_Instruction.eVMI_CONV, eVM_Type, eVM_Type.eVMT_Bool); TypeStack.Push(eVM_Type.eVMT_Bool); } break; case eToken.eBitOr: case eToken.eBitAnd: case eToken.eBitXor: case eToken.eBitShiftLeft: case eToken.eBitShiftRight: if (eVM_Type == eVM_Type.eVMT_Int) { TypeStack.Pop(); Emit(eVM_Instruction.eVMI_CONV, eVM_Type, eVM_Type.eVMT_Int); TypeStack.Push(eVM_Type.eVMT_Int); } break; } }
private void CompileUnary(GMLToken _tok) { CompileExpression(_tok.Children[0]); eVM_Type eVM_Type = TypeStack.Peek(); switch (_tok.Id) { case 203: switch (eVM_Type) { case eVM_Type.eVMT_String: case eVM_Type.eVMT_Error: Error("Unable to Not a string", _tok); break; case eVM_Type.eVMT_Double: case eVM_Type.eVMT_Float: case eVM_Type.eVMT_Int: case eVM_Type.eVMT_Long: case eVM_Type.eVMT_Variable: TypeStack.Pop(); Emit(eVM_Instruction.eVMI_CONV, eVM_Type, eVM_Type.eVMT_Bool); TypeStack.Push(eVM_Type.eVMT_Bool); eVM_Type = eVM_Type.eVMT_Bool; break; } Emit(eVM_Instruction.eVMI_NOT, eVM_Type); break; case 211: Emit(eVM_Instruction.eVMI_NEG, eVM_Type); break; case 220: switch (eVM_Type) { case eVM_Type.eVMT_String: case eVM_Type.eVMT_Error: Error("Unable to Negate a string", _tok); break; case eVM_Type.eVMT_Double: case eVM_Type.eVMT_Float: case eVM_Type.eVMT_Variable: TypeStack.Pop(); Emit(eVM_Instruction.eVMI_CONV, eVM_Type, eVM_Type.eVMT_Int); TypeStack.Push(eVM_Type.eVMT_Int); eVM_Type = eVM_Type.eVMT_Int; break; } Emit(eVM_Instruction.eVMI_NOT, eVM_Type); break; } }
private void Dig(InstructionDependency[] preds, int index) { var otypes = new TypeDescriptor[index + 1]; var rtypes = new TypeDescriptor[index + 1]; for (int i = 0; i < otypes.Length; i++) { otypes[i] = TypeStack.ElementAt(index - i); rtypes[i] = TypeStack.ElementAt(i == index ? index : index - i - 1); } Emit(DefaultInstructionSet.Instance.Dig(index).CreateStk(preds, otypes, rtypes)); }
protected override void ProcessInstruction(XILSInstr i) { var rTypes = i.ResultTypes; var opTypes = new TypeDescriptor[i.OperandTypes.Length]; for (int j = 0; j < opTypes.Length; j++) { opTypes[j] = TypeStack.ElementAt(opTypes.Length - 1 - j); } var inew = i.Command.CreateStk(i.Preds, opTypes, rTypes); base.ProcessInstruction(inew); }
private void CompileFunction(GMLToken _tok) { foreach (GMLToken child in _tok.Children) { CompileExpression(child); eVM_Type eVM_Type = TypeStack.Pop(); if (eVM_Type != eVM_Type.eVMT_Variable) { Emit(eVM_Instruction.eVMI_CONV, eVM_Type, eVM_Type.eVMT_Variable); } } EmitI(eVM_Instruction.eVMI_CALL, _tok.Id); TypeStack.Push(GMAssetCompiler.eVM_Type.eVMT_Variable); }
private void CompileConstant(GMLToken _tok) { switch (_tok.Value.Kind) { case eKind.eConstant: Error("constant token", _tok); break; case eKind.eNone: Error("None constant token", _tok); break; case eKind.eNumber: { double num = (long)_tok.Value.ValueI; if (num == _tok.Value.ValueI) { long num2 = (long)_tok.Value.ValueI; if (num2 > int.MaxValue || num2 < int.MinValue) { EmitI(eVM_Instruction.eVMI_PUSH, num2); TypeStack.Push(eVM_Type.eVMT_Long); } else if (num2 > 32767 || num2 < -32768) { EmitI(eVM_Instruction.eVMI_PUSH, (int)num2); TypeStack.Push(eVM_Type.eVMT_Int); } else { VMB.Add(VMBuffer.EncodeInstructionArg(192, 15) | (int)(num2 & 0xFFFF)); TypeStack.Push(eVM_Type.eVMT_Int); } } else { EmitI(eVM_Instruction.eVMI_PUSH, _tok.Value.ValueI); TypeStack.Push(eVM_Type.eVMT_Double); } break; } case eKind.eString: EmitI(eVM_Instruction.eVMI_PUSH, _tok.Value.ValueS); TypeStack.Push(eVM_Type.eVMT_String); break; } }
private void AnalyzeUsage(INamedTypeSymbol symbol) { if (!ValidateUsage(symbol)) { return; } if (symbol.ContainingAssembly != Assembly) { if (!SolutionAssemblyNames.Contains(symbol.ContainingAssembly.MetadataName)) { // filter out target types from outside of our solution assemblies return; } ExternalTypesUsed.Add(symbol); if (TypeStack.Count > 0) { var dependentSet = GetDependentsSet(symbol); dependentSet.Add(TypeStack.Peek()); } } }
private bool SubsumedInner(DataType type1, DataType type2, TypeStack typeStack) { if (typeStack.Contains(type1, type2)) { return(true); } if (type1.IsUnknownType() || type1 == DataType.None || type1.Equals(type2)) { return(true); } if (type1 is TupleType tuple1 && type2 is TupleType tuple2) { List <DataType> elems1 = tuple1.eltTypes; List <DataType> elems2 = tuple2.eltTypes; if (elems1.Count == elems2.Count) { typeStack.Push(type1, type2); for (int i = 0; i < elems1.Count; i++) { if (!SubsumedInner(elems1[i], elems2[i], typeStack)) { typeStack.Pop(type1, type2); return(false); } } } return(true); } if (type1 is ListType list1 && type2 is ListType list2) { return(SubsumedInner(list1.ToTupleType(), list2.ToTupleType(), typeStack)); } return(false); }
private bool subsumedInner(DataType type1, DataType type2, TypeStack typeStack) { if (typeStack.contains(type1, type2)) { return(true); } if (type1.isUnknownType() || type1 == DataType.None || type1.Equals(type2)) { return(true); } if (type1 is TupleType && type2 is TupleType) { List <DataType> elems1 = ((TupleType)type1).eltTypes; List <DataType> elems2 = ((TupleType)type2).eltTypes; if (elems1.Count == elems2.Count) { typeStack.push(type1, type2); for (int i = 0; i < elems1.Count; i++) { if (!subsumedInner(elems1[i], elems2[i], typeStack)) { typeStack.pop(type1, type2); return(false); } } } return(true); } if (type1 is ListType && type2 is ListType) { return(subsumedInner(((ListType)type1).toTupleType(), ((ListType)type2).toTupleType(), typeStack)); } return(false); }
private void ProcessStoreVariable(XILSInstr i) { var lit = (IStorableLiteral)i.StaticOperand; var local = lit as Variable; IStorableLiteral newLit; if (local != null) { Variable newLocal; if (!_localDic.TryGetValue(local.Name, out newLocal)) { newLocal = new Variable(TypeStack.Peek()) { Name = local.Name }; _localDic[local.Name] = newLocal; } newLit = newLocal; } else { newLit = lit; } var preds = RemapPreds(i.Preds); if (!TypeStack.Peek().Equals(newLit.Type)) { Convert(preds, TypeStack.Peek(), newLit.Type); preds = new InstructionDependency[0]; } var inew = new XILSInstr( DefaultInstructionSet.Instance.StoreVar(newLit), preds, new TypeDescriptor[] { newLit.Type }, new TypeDescriptor[0]); Emit(inew); }
/// <summary> /// Emit code to load a value onto the stack /// </summary> /// <param name="name"></param> /// <param name="types"></param> public void Load(VariableName name, TypeStack <TEmit> types) { // Check if we know what type this variable is var type = _types.TypeOf(name) ?? StackType.YololValue; if (_cache.ContainsKey(name)) { var local = _cache[name]; _emitter.LoadLocal(local.Local); ConvertType(local.Type, type); types.Push(type); } else { // Load from backing store EmitLoadValue(name); // Unbox it to that type (bypassing dynamic type checking) StaticUnbox(type); types.Push(type); } }
private void Initialize() { Contexts.Push(this); TypeStack.Push(ModelType); var serializable = Model as ISerializable; if (serializable != null) { var registrationInfo = ReferenceManager.GetInfo(serializable, Context.ShouldAutoGenerateGraphIds(this)); //// Note: we need to use the x.Tag instead of x.Instance.ContextMode here because we might be serializing a different thing //switch ((SerializationContextMode)x.Tag) switch (ContextMode) { case SerializationContextMode.Serialization: if (!registrationInfo.HasCalledSerializing) { serializable.StartSerialization(); registrationInfo.HasCalledSerializing = true; } break; case SerializationContextMode.Deserialization: if (!registrationInfo.HasCalledDeserializing) { serializable.StartDeserialization(); registrationInfo.HasCalledDeserializing = true; } break; default: throw new ArgumentOutOfRangeException(); } } }
private void Uninitialize() { var serializable = Model as ISerializable; if (serializable != null) { var registrationInfo = ReferenceManager.GetInfo(serializable); //// Note: we need to use the x.Tag instead of x.Instance.ContextMode here because we might be serializing a different thing //switch ((SerializationContextMode)x.Tag) switch (ContextMode) { case SerializationContextMode.Serialization: if (!registrationInfo.HasCalledSerialized) { serializable.FinishSerialization(); registrationInfo.HasCalledSerialized = true; } break; case SerializationContextMode.Deserialization: if (!registrationInfo.HasCalledDeserialized) { serializable.FinishDeserialization(); registrationInfo.HasCalledDeserialized = true; } break; default: throw new ArgumentOutOfRangeException(); } } TypeStack.Pop(); Contexts.Pop(); }
private void HandleLoadVar(XILSInstr i) { Tuple <int, int> stackRef; if (_read2write.TryGetValue(i.Index, out stackRef)) { int stackP = _resultStack.IndexOf(stackRef); Debug.Assert(stackP >= 0); Debug.Assert(_resultStack.Count == TypeStack.Count); int depth = _resultStack.Count; int relP = depth - stackP - 1; if (relP > 0) { var preds = RemapPreds(i.Preds); TypeDescriptor[] opTypes = TypeStack.Take(depth - stackP).Reverse().ToArray(); Debug.Assert(opTypes.First().Equals(i.ResultTypes[0])); TypeDescriptor[] rTypes = (TypeDescriptor[])opTypes.Clone(); for (int j = 1; j <= relP; j++) { var tmp = rTypes[j]; rTypes[j] = rTypes[j - 1]; rTypes[j - 1] = tmp; var tmpi = _resultStack[stackP + j]; _resultStack[stackP + j] = _resultStack[stackP + j - 1]; _resultStack[stackP + j - 1] = tmpi; } TypeDescriptor[] allTypes = opTypes.Concat(rTypes).ToArray(); base.Emit(DefaultInstructionSet.Instance.Dig(relP).CreateStk(preds, opTypes.Length, allTypes)); } } else { ProcessDefault(i); } }
private void CompileBinary(GMLToken _tok) { CompileExpression(_tok.Children[0]); BinaryTypeCoercion(_tok, 1); CompileExpression(_tok.Children[2]); BinaryTypeCoercion(_tok, 2); eVM_Type eVM_Type = TypeStack.Pop(); eVM_Type eVM_Type2 = TypeStack.Pop(); int num = TypeSize(eVM_Type); int num2 = TypeSize(eVM_Type2); eVM_Type item = (num > num2) ? eVM_Type : eVM_Type2; switch (_tok.Children[1].Token) { case eToken.eTime: Emit(eVM_Instruction.eVMI_MUL, eVM_Type, eVM_Type2); TypeStack.Push(item); break; case eToken.eDivide: Emit(eVM_Instruction.eVMI_DIV, eVM_Type, eVM_Type2); TypeStack.Push(item); break; case eToken.eDiv: Emit(eVM_Instruction.eVMI_REM, eVM_Type, eVM_Type2); TypeStack.Push(item); break; case eToken.eMod: Emit(eVM_Instruction.eVMI_MOD, eVM_Type, eVM_Type2); TypeStack.Push(item); break; case eToken.ePlus: Emit(eVM_Instruction.eVMI_ADD, eVM_Type, eVM_Type2); TypeStack.Push(item); break; case eToken.eMinus: Emit(eVM_Instruction.eVMI_SUB, eVM_Type, eVM_Type2); TypeStack.Push(item); break; case eToken.eLess: Emit(eVM_Instruction.eVMI_SET_LT, eVM_Type, eVM_Type2); TypeStack.Push(eVM_Type.eVMT_Bool); break; case eToken.eLessEqual: Emit(eVM_Instruction.eVMI_SET_LE, eVM_Type, eVM_Type2); TypeStack.Push(eVM_Type.eVMT_Bool); break; case eToken.eAssign: case eToken.eEqual: Emit(eVM_Instruction.eVMI_SET_EQ, eVM_Type, eVM_Type2); TypeStack.Push(eVM_Type.eVMT_Bool); break; case eToken.eNotEqual: Emit(eVM_Instruction.eVMI_SET_NE, eVM_Type, eVM_Type2); TypeStack.Push(eVM_Type.eVMT_Bool); break; case eToken.eGreaterEqual: Emit(eVM_Instruction.eVMI_SET_GE, eVM_Type, eVM_Type2); TypeStack.Push(eVM_Type.eVMT_Bool); break; case eToken.eGreater: Emit(eVM_Instruction.eVMI_SET_GT, eVM_Type, eVM_Type2); TypeStack.Push(eVM_Type.eVMT_Bool); break; case eToken.eAnd: case eToken.eBitAnd: Emit(eVM_Instruction.eVMI_AND, eVM_Type, eVM_Type2); TypeStack.Push(item); break; case eToken.eOr: case eToken.eBitOr: Emit(eVM_Instruction.eVMI_OR, eVM_Type, eVM_Type2); TypeStack.Push(item); break; case eToken.eXor: case eToken.eBitXor: Emit(eVM_Instruction.eVMI_XOR, eVM_Type, eVM_Type2); TypeStack.Push(item); break; case eToken.eBitShiftLeft: Emit(eVM_Instruction.eVMI_SHL, eVM_Type, eVM_Type2); TypeStack.Push(item); break; case eToken.eBitShiftRight: Emit(eVM_Instruction.eVMI_SHR, eVM_Type, eVM_Type2); TypeStack.Push(item); break; } }
private void Swap(InstructionDependency[] preds) { Emit(DefaultInstructionSet.Instance.Dig(1).CreateStk(preds, 2, TypeStack.ElementAt(1), TypeStack.Peek(), TypeStack.Peek(), TypeStack.ElementAt(1))); }
private void EmitIndexComputation(Array array) { MemoryMappedStorage mms = GetDataLayout(array); ArrayMemoryLayout layout = mms.Layout as ArrayMemoryLayout; if (layout.ElementsPerWord > 1) { throw new NotImplementedException("Multiple elements per word not yet implemented"); } MemoryRegion region = mms.Region; IMarshalInfo minfo = region.MarshalInfo; int shiftWidth = MathExt.CeilLog2(mms.Region.AddressWidth); TypeDescriptor indexType = TypeDescriptor.GetTypeOf(mms.BaseAddress); for (int i = 0; i < layout.Strides.Length; i++) { TypeDescriptor orgIndexType; if (i > 0) { orgIndexType = TypeStack.Skip(1).First(); Emit(_iset.Swap().CreateStk(2, orgIndexType, indexType, indexType, orgIndexType)); } else { orgIndexType = TypeStack.Peek(); } ulong stride = layout.Strides[layout.Strides.Length - i - 1]; if (MathExt.IsPow2(stride)) { Emit(_iset.Convert().CreateStk(1, orgIndexType, indexType)); int ishift = MathExt.CeilLog2(stride); if (ishift > 0) { Unsigned shift = Unsigned.FromULong((ulong)ishift, shiftWidth); TypeDescriptor shiftType = TypeDescriptor.GetTypeOf(shift); Emit(_iset.LdConst(shift).CreateStk(0, shiftType)); Emit(_iset.LShift().CreateStk(2, indexType, shiftType, indexType)); } } else { throw new NotImplementedException("Stride ain't a power of 2"); } if (i > 0) { Emit(_iset.Or().CreateStk(2, indexType, indexType, indexType)); } } if (mms.BaseAddress.ULongValue != 0) { Emit(_iset.LdConst(mms.BaseAddress).CreateStk(0, indexType)); if (minfo.UseStrongPow2Alignment) { Emit(_iset.Or().CreateStk(2, indexType, indexType, indexType)); } else { Emit(_iset.Add().CreateStk(2, indexType, indexType, indexType)); } } }
private void CompileAssign(GMLToken _tok) { switch (_tok.Children[1].Token) { case eToken.eAssign: CompileExpression(_tok.Children[2]); CompilePop(_tok.Children[0], TypeStack.Pop()); break; case eToken.eAssignPlus: { CompileVariable(_tok.Children[0]); TypeStack.Pop(); CompileExpression(_tok.Children[2]); eVM_Type eVM_Type3 = TypeStack.Pop(); if (eVM_Type3 == eVM_Type.eVMT_Bool) { Emit(eVM_Instruction.eVMI_CONV, eVM_Type3, eVM_Type.eVMT_Int); eVM_Type3 = eVM_Type.eVMT_Int; } Emit(eVM_Instruction.eVMI_ADD, eVM_Type3, eVM_Type.eVMT_Variable); CompilePop(_tok.Children[0], eVM_Type.eVMT_Variable); break; } case eToken.eAssignMinus: { CompileVariable(_tok.Children[0]); TypeStack.Pop(); CompileExpression(_tok.Children[2]); eVM_Type eVM_Type7 = TypeStack.Pop(); if (eVM_Type7 == eVM_Type.eVMT_Bool) { Emit(eVM_Instruction.eVMI_CONV, eVM_Type7, eVM_Type.eVMT_Int); eVM_Type7 = eVM_Type.eVMT_Int; } Emit(eVM_Instruction.eVMI_SUB, eVM_Type7, eVM_Type.eVMT_Variable); CompilePop(_tok.Children[0], eVM_Type.eVMT_Variable); break; } case eToken.eAssignTimes: { CompileVariable(_tok.Children[0]); TypeStack.Pop(); CompileExpression(_tok.Children[2]); eVM_Type eVM_Type2 = TypeStack.Pop(); if (eVM_Type2 == eVM_Type.eVMT_Bool) { Emit(eVM_Instruction.eVMI_CONV, eVM_Type2, eVM_Type.eVMT_Int); eVM_Type2 = eVM_Type.eVMT_Int; } Emit(eVM_Instruction.eVMI_MUL, eVM_Type2, eVM_Type.eVMT_Variable); CompilePop(_tok.Children[0], eVM_Type.eVMT_Variable); break; } case eToken.eAssignDivide: { CompileVariable(_tok.Children[0]); TypeStack.Pop(); CompileExpression(_tok.Children[2]); eVM_Type eVM_Type6 = TypeStack.Pop(); if (eVM_Type6 == eVM_Type.eVMT_Bool) { Emit(eVM_Instruction.eVMI_CONV, eVM_Type6, eVM_Type.eVMT_Int); eVM_Type6 = eVM_Type.eVMT_Int; } Emit(eVM_Instruction.eVMI_DIV, eVM_Type6, eVM_Type.eVMT_Variable); CompilePop(_tok.Children[0], eVM_Type.eVMT_Variable); break; } case eToken.eAssignOr: { CompileVariable(_tok.Children[0]); TypeStack.Pop(); CompileExpression(_tok.Children[2]); eVM_Type eVM_Type4 = TypeStack.Pop(); if (eVM_Type4 != eVM_Type.eVMT_Int && eVM_Type4 != eVM_Type.eVMT_Long) { Emit(eVM_Instruction.eVMI_CONV, eVM_Type4, eVM_Type.eVMT_Int); eVM_Type4 = eVM_Type.eVMT_Int; } Emit(eVM_Instruction.eVMI_OR, eVM_Type4, eVM_Type.eVMT_Variable); CompilePop(_tok.Children[0], eVM_Type.eVMT_Variable); break; } case eToken.eAssignAnd: { CompileVariable(_tok.Children[0]); TypeStack.Pop(); CompileExpression(_tok.Children[2]); eVM_Type eVM_Type5 = TypeStack.Pop(); if (eVM_Type5 != eVM_Type.eVMT_Int && eVM_Type5 != eVM_Type.eVMT_Long) { Emit(eVM_Instruction.eVMI_CONV, eVM_Type5, eVM_Type.eVMT_Int); eVM_Type5 = eVM_Type.eVMT_Int; } Emit(eVM_Instruction.eVMI_AND, eVM_Type5, eVM_Type.eVMT_Variable); CompilePop(_tok.Children[0], eVM_Type.eVMT_Variable); break; } case eToken.eAssignXor: { CompileVariable(_tok.Children[0]); TypeStack.Pop(); CompileExpression(_tok.Children[2]); eVM_Type eVM_Type = TypeStack.Pop(); if (eVM_Type != eVM_Type.eVMT_Int && eVM_Type != eVM_Type.eVMT_Long) { Emit(eVM_Instruction.eVMI_CONV, eVM_Type, eVM_Type.eVMT_Int); eVM_Type = eVM_Type.eVMT_Int; } Emit(eVM_Instruction.eVMI_XOR, eVM_Type, eVM_Type.eVMT_Variable); CompilePop(_tok.Children[0], eVM_Type.eVMT_Variable); break; } } }
public State() { stack = new TypeStack(); }