00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
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
00066
00067
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
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 }