// bytecode gen for all inputs of the node void BuildByteCodeForInput(BytecodeGenContext byteCodeContext, ScriptNodeConnection inputConn) { var node = inputConn.InputElement.As <ScriptNode>(); var linkCache = node.As <ScriptNodeLinkCache>(); // create a copy of links var allLinks = new List <ScriptNodeConnection>(linkCache.ToThisNode); // foreach (var input in node.AllInputPins) { var samePinLinks = allLinks.Where(con => con.InputPin == input).ToList(); // remove from processed pins if (samePinLinks != null) { foreach (var inputProcessing in samePinLinks) { allLinks.Remove(inputProcessing); } } var propertyType = ToPropertyType(input.TypeName); // we are handling this node, so other input signal has no meaning if (propertyType == PropertyType.Signal) { //Outputs.WriteLine(OutputMessageType.Warning, "Multiple input signal type for {0}, ignoring", node.Id); continue; } // build bytecode for the input DFS traversal BuildByteCodeForNode(byteCodeContext, linkCache, input, samePinLinks); } }
void BuildByteCode_AppendBooleanPin(BytecodeGenContext byteCodeContext, ScriptNodeLinkCache linkCache, ICircuitPin inputPin, IList <ScriptNodeConnection> samePinLinks) { if (samePinLinks.Count != 1) { throw new Exception("Invalid link count for " + inputPin.Name); } var connection = samePinLinks[0]; var outElement = connection.OutputElement; var outLinkCache = outElement.As <ScriptNodeLinkCache>(); }
// DFS traversal based bytecode gen void BuildByteCodeForNode(BytecodeGenContext byteCodeContext, ScriptNodeLinkCache linkCache, ICircuitPin inputPin, IList <ScriptNodeConnection> samePinLinks) { if (samePinLinks == null || samePinLinks.Count == 0) // if nothing linked just take constant { var node = linkCache.As <ScriptNode>(); BuildByteCode_AppendPropertyValueLoad(byteCodeContext, node.DomNode, inputPin); } else { delByteCodeHandler byteCodeHandler; if (!m_ByteCodeGen.TryGetValue(inputPin.TypeName.ToString(), out byteCodeHandler)) { throw new Exception("Bytecode handler not found for :" + inputPin.TypeName.ToString()); } byteCodeHandler(byteCodeContext, linkCache, inputPin, samePinLinks); } // }
void CompileInterface(TongCompilerContext.DocumentContext docContext, ScriptNode interfaceNode) { var linkCache = interfaceNode.As <ScriptNodeLinkCache>(); var signalConnections = GetSignalOutputs(linkCache); if (signalConnections.Count == 0) { return; } // interface only allow single output if (signalConnections.Count > 1) { return; } BytecodeGenContext byteCodeGenContext = new BytecodeGenContext(); BuildByteCodeForInput(byteCodeGenContext, signalConnections[0]); docContext.CompiledInterfaces.Add(byteCodeGenContext.Builder); }
void BuildByteCode_AppendPropertyValueLoad(BytecodeGenContext byteCodeContext, DomNode node, ICircuitPin inputPin) { var attrInfo = node.Type.GetAttributeInfo(inputPin.Name.ToString()); var value = node.GetAttribute(attrInfo); if (value == null) { byteCodeContext.Builder.AppendLoadI(0); return; } switch (attrInfo.Type.Name) { case "boolean": byteCodeContext.Builder.AppendLoadI((bool)value ? 1 : 0); break; case "decimal": decimal decVal = (decimal)value; if ((decVal - (Int64)decVal) != 0) { byteCodeContext.Builder.AppendLoadF((float)decVal); } else { byteCodeContext.Builder.AppendLoadI((int)decVal); } break; case "double": double dblVal = (double)value; if ((dblVal - (Int64)dblVal) != 0) { byteCodeContext.Builder.AppendLoadF((float)dblVal); } else { byteCodeContext.Builder.AppendLoadI((int)dblVal); } break; case "float": float fltVal = (float)value; if ((fltVal - (Int64)fltVal) != 0) { byteCodeContext.Builder.AppendLoadF(fltVal); } else { byteCodeContext.Builder.AppendLoadI((int)fltVal); } break; case "int": byteCodeContext.Builder.AppendLoadI((int)value); break; case "string": byteCodeContext.Builder.AppendLoadString((string)value); break; default: throw new Exception("Not supported load bytecode type:" + attrInfo.Type.Name); } }
void BuildByteCode_AppendIntPin(BytecodeGenContext byteCodeContext, ScriptNodeLinkCache linkCache, ICircuitPin inputPin, IList <ScriptNodeConnection> samePinLinks) { }