Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

ShSyntax.cpp

00001 // Sh: A GPU metaprogramming language.
00002 //
00003 // Copyright (c) 2003 University of Waterloo Computer Graphics Laboratory
00004 // Project administrator: Michael D. McCool
00005 // Authors: Zheng Qin, Stefanus Du Toit, Kevin Moule, Tiberiu S. Popa,
00006 //          Michael D. McCool
00007 // 
00008 // This software is provided 'as-is', without any express or implied
00009 // warranty. In no event will the authors be held liable for any damages
00010 // arising from the use of this software.
00011 // 
00012 // Permission is granted to anyone to use this software for any purpose,
00013 // including commercial applications, and to alter it and redistribute it
00014 // freely, subject to the following restrictions:
00015 // 
00016 // 1. The origin of this software must not be misrepresented; you must
00017 // not claim that you wrote the original software. If you use this
00018 // software in a product, an acknowledgment in the product documentation
00019 // would be appreciated but is not required.
00020 // 
00021 // 2. Altered source versions must be plainly marked as such, and must
00022 // not be misrepresented as being the original software.
00023 // 
00024 // 3. This notice may not be removed or altered from any source
00025 // distribution.
00027 #include <iostream>
00028 #include <fstream>
00029 #include <cassert>
00030 #include "ShSyntax.hpp"
00031 #include "ShEnvironment.hpp"
00032 #include "ShContext.hpp"
00033 #include "ShTokenizer.hpp"
00034 #include "ShToken.hpp"
00035 #include "ShProgram.hpp"
00036 #include "ShBackend.hpp"
00037 #include "ShOptimizations.hpp"
00038 
00039 namespace SH {
00040 
00041 ShProgram shBeginShader(const std::string& target)
00042 {
00043   ShProgram prg(target);
00044   ShContext::current()->enter(prg.node());
00045   return prg;
00046 }
00047 
00048 void shEndShader()
00049 {
00050   ShContext* context = ShContext::current();
00051 
00052   ShProgramNodePtr parsing = context->parsing();
00053   assert(parsing);
00054   
00055   parsing->ctrlGraph = new ShCtrlGraph(parsing->tokenizer.blockList());
00056 
00057   optimize(parsing);
00058   
00059   parsing->collectVariables();
00060   
00061   context->exit();
00062 
00063   parsing->finish();
00064 
00065   // TODO. See issue129.
00066 //   if (!ShEnvironment::shader->target().empty()) {
00067 //     shCompile(ShEnvironment::shader);
00068 //   }
00069 }
00070 
00071 void shCompile(ShProgram& prg)
00072 {
00073   if (!ShEnvironment::backend) return;
00074   prg.compile(ShEnvironment::backend);
00075 }
00076 
00077 void shCompile(ShProgram& prg, const std::string& target)
00078 {
00079   if (!ShEnvironment::backend) return;
00080   prg.compile(target, ShEnvironment::backend);
00081 }
00082 
00083 void shCompileShader(ShProgram& prg)
00084 {
00085   shCompile(prg);
00086 }
00087 
00088 void shCompileShader(const std::string& target, ShProgram& prg)
00089 {
00090   shCompile(prg, target);
00091 }
00092 
00093 void shBind(ShProgram& prg)
00094 {
00095   if (!ShEnvironment::backend) return;
00096   prg.code(ShEnvironment::backend)->bind();
00097 }
00098 
00099 void shBind(const std::string& target, ShProgram& prg)
00100 {
00101   if (!ShEnvironment::backend) return;
00102   prg.code(target, ShEnvironment::backend)->bind();
00103 }
00104 
00105 typedef std::map<std::string, ShProgram> BoundProgramMap;
00106 
00107 void shUpdate()
00108 {
00109   if (!ShEnvironment::backend) return;
00110   
00111   for (BoundProgramMap::iterator i = ShContext::current()->begin_bound(); 
00112        i != ShContext::current()->end_bound(); i++) {
00113     i->second.code(ShEnvironment::backend)->update();
00114   }
00115 }
00116 
00117 void shBindShader(ShProgram& shader)
00118 {
00119   shBind(shader);
00120 }
00121 
00122 void shBindShader(const std::string& target, ShProgram& shader)
00123 {
00124   shBind(target, shader);
00125 }
00126 
00127 bool shSetBackend(const std::string& name)
00128 {
00129   ShBackendPtr backend = SH::ShBackend::lookup(name);
00130   if (!backend) return false;
00131   SH::ShEnvironment::backend = backend;
00132   return true;
00133 }
00134 
00135 bool shEvaluateCondition(const ShVariable& arg)
00136 {
00137   bool cond = false;
00138   for (int i = 0; i < arg.size(); i++) {
00139     cond = cond || arg.getVariant(i)->isTrue();
00140   }
00141   return cond;
00142 }
00143 
00144 
00145 bool shProcessArg(const ShVariable& arg,
00146                   bool* internal_cond)
00147 {
00148   if (ShContext::current()->parsing()) {
00149     ShContext::current()->parsing()->tokenizer.processArg(arg);
00150   } else {
00151     if (internal_cond) *internal_cond = shEvaluateCondition(arg);
00152   }
00153   return true;
00154 }
00155 
00156 bool shPushArgQueue()
00157 {
00158   if (ShContext::current()->parsing()) ShContext::current()->parsing()->tokenizer.pushArgQueue();
00159   return true;
00160 }
00161 
00162 bool shPushArg()
00163 {
00164   if (ShContext::current()->parsing()) ShContext::current()->parsing()->tokenizer.pushArg();
00165   return true;
00166 }
00167 
00168 void shInit()
00169 {
00170   ShContext::current();
00171   // TODO: Initialize backends
00172 }
00173 
00174 void shIf(bool)
00175 {
00176   if (!ShContext::current()->parsing()) return;
00177   ShPointer<ShToken> token = new ShToken(SH_TOKEN_IF);
00178     
00179   token->arguments.push_back(ShContext::current()->parsing()->tokenizer.getArgument());
00180   ShContext::current()->parsing()->tokenizer.popArgQueue();
00181     
00182   ShContext::current()->parsing()->tokenizer.blockList()->addBlock(token);
00183 }
00184 
00185 void shEndIf()
00186 {
00187   if (!ShContext::current()->parsing()) return;
00188   ShContext::current()->parsing()->tokenizer.blockList()->addBlock(new ShToken(SH_TOKEN_ENDIF));
00189 }
00190 
00191 void shElse()
00192 {
00193   if (!ShContext::current()->parsing()) return;
00194   ShContext::current()->parsing()->tokenizer.blockList()->addBlock(new ShToken(SH_TOKEN_ELSE));
00195 }
00196 
00197 void shWhile(bool)
00198 {
00199   if (!ShContext::current()->parsing()) return;
00200   ShPointer<ShToken> token = new ShToken(SH_TOKEN_WHILE);
00201 
00202   token->arguments.push_back(ShContext::current()->parsing()->tokenizer.getArgument());
00203   ShContext::current()->parsing()->tokenizer.popArgQueue();
00204 
00205   ShContext::current()->parsing()->tokenizer.blockList()->addBlock(token);
00206 }
00207 
00208 void shEndWhile()
00209 {
00210   if (!ShContext::current()->parsing()) return;
00211   ShContext::current()->parsing()->tokenizer.blockList()->addBlock(new ShToken(SH_TOKEN_ENDWHILE));
00212 }
00213 
00214 void shDo()
00215 {
00216   if (!ShContext::current()->parsing()) return;
00217   ShContext::current()->parsing()->tokenizer.blockList()->addBlock(new ShToken(SH_TOKEN_DO));
00218 }
00219 
00220 void shUntil(bool)
00221 {
00222   if (!ShContext::current()->parsing()) return;
00223   ShPointer<ShToken> token = new ShToken(SH_TOKEN_UNTIL);
00224 
00225   token->arguments.push_back(ShContext::current()->parsing()->tokenizer.getArgument());
00226   ShContext::current()->parsing()->tokenizer.popArgQueue();
00227 
00228   ShContext::current()->parsing()->tokenizer.blockList()->addBlock(token);
00229 }
00230 
00231 void shFor(bool)
00232 {
00233   if (!ShContext::current()->parsing()) return;
00234   ShPointer<ShToken> token = new ShToken(SH_TOKEN_FOR);
00235 
00236   for (int i = 0; i < 3; i++) {
00237     token->arguments.push_back(ShContext::current()->parsing()->tokenizer.getArgument());
00238   }
00239   ShContext::current()->parsing()->tokenizer.popArgQueue();
00240 
00241   ShContext::current()->parsing()->tokenizer.blockList()->addBlock(token);
00242 }
00243 
00244 void shEndFor()
00245 {
00246   if (!ShContext::current()->parsing()) return;
00247   ShContext::current()->parsing()->tokenizer.blockList()->addBlock(new ShToken(SH_TOKEN_ENDFOR));
00248 }
00249 
00250 void ShBreak()
00251 {
00252   if (!ShContext::current()->parsing()) return;
00253   ShContext::current()->parsing()->tokenizer.blockList()->addBlock(new ShToken(SH_TOKEN_BREAK));
00254 }
00255 
00256 void ShContinue()
00257 {
00258   if (!ShContext::current()->parsing()) return;
00259   ShContext::current()->parsing()->tokenizer.blockList()->addBlock(new ShToken(SH_TOKEN_CONTINUE));
00260 }
00261 
00262 }

Generated on Mon Jan 24 18:36:35 2005 for Sh by  doxygen 1.4.1