/* Theoretic - Graph Theoretic Byte Code Engineering * Copyright (C) 2001-2002 Jay Freeman (saurik) */ /* * Redistribution and use in source and binary * forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the * above copyright notice, this list of conditions * and the following disclaimer. * 2. Redistributions in binary form must reproduce the * above copyright notice, this list of conditions * and the following disclaimer in the documentation * and/or other materials provided with the * distribution. * 3. The name of the author may not be used to endorse * or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "stdafx.h" #include "theoretic/Operation.h" #include "theoretic/OpGraph.h" namespace Theoretic { Operation::Operation() { } Operation::Operation(const Operation &op) : name(op.GetName()), stackin(op.stackin), stackout(op.stackout) { args_ = op.GetArgs(); links_ = op.GetLinks(); } Operation::Operation(const Operation &op, const std::wstring &name) : name(name), stackin(op.stackin), stackout(op.stackout) { args_ = op.GetArgs(); links_ = op.GetLinks(); } Operation::Operation(const std::wstring &name) : name(name) {} Operation::Operation(const std::wstring &name, unsigned stackin, unsigned stackout) : name(name), stackin(stackin), stackout(stackout) {} Operation::~Operation() { } VObjectPtr &Operation::operator [](const std::wstring &name) { return args_[name]; } OpList &Operation::operator ()(const std::wstring &name) { return links_[name]; } std::wstring Operation::GetName() const { return name; } const Operation::LinkMap &Operation::GetLinks() const { return links_; } Operation::LinkMap &Operation::GetLinks() { return links_; } const NamedVMap &Operation::GetArgs() const { return args_; } NamedVMap &Operation::GetArgs() { return args_; } void Operation::Cement(const Metallurgy::Method &method) { assert(false); } bool Operation::ResolveStack(OpGraph *graph, Operation *parent) { while (stackin != 0) { OpGraph::LinkList links = graph->BackLinks(this); if (links.size() == 1) { if (links[0].first->ResolveStack(graph, this)) operator ()(L"stack")[--stackin] = links[0].first; } else { assert(links.size() != 0); for (OpGraph::LinkList::iterator link = links.begin() + 1; link != links.end(); ++link) { Operation *clone = new Operation(*this); graph->Add(clone); OpGraph::LinkRef &ref = link->second; (*link->first)(ref.first)[ref.second] = clone; } return false; } } if (parent != NULL) { links_.erase(L"next"); graph->Graft(this, parent); } return true; } bool Operation::Resolvable() const { return stackin != 0; } THEORETIC_API std::wostream &operator <<(std::wostream &out, const Operation &op) { out << L"(" << &op << L") " << op.GetName() << L"\r\n"; const NamedVMap &args = op.GetArgs(); for (NamedVMap::const_iterator arg = args.begin(); arg != args.end(); ++arg) out << L" $" << arg->first << L" = " << arg->second << L"\r\n"; const Operation::LinkMap &links = op.GetLinks(); for (Operation::LinkMap::const_iterator link = links.begin(); link != links.end(); ++link) out << L" " << link->first << L" -> (" << link->second << L")\r\n"; return out; } }