builder.cc

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2008 Kamil Dudka <xdudka00@stud.fit.vutbr.cz>
00003  *
00004  * This file is part of vyp08 (compiler and interpreter of VYP08 language).
00005  *
00006  * vyp08 is free software: you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation, either version 3 of the License, or
00009  * any later version.
00010  *
00011  * vyp08 is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with vyp08.  If not, see <http://www.gnu.org/licenses/>.
00018  */
00019 
00020 #include "config.h"
00021 #include "builder.h"
00022 
00023 #include "cmd.h"
00024 #include "parser.h"
00025 #include "vm.h"
00026 #include "vypIO.h"
00027 
00028 #ifndef BUILDING_DOX
00029 #   include <stack>
00030 #   include <string>
00031 #endif
00032 
00033 using namespace StreamDecorator;
00034 using std::string;
00035 
00037 class Builder: public IBuilder {
00038     public:
00039         Builder(Vm *);
00040         virtual ~Builder();
00041         virtual bool hasError() const { return hasError_; }
00042         virtual void errorDetected();
00043         virtual void glVar(EToken type, Token id);
00044         virtual void fncDeclInit(EToken type, Token id);
00045         virtual void fncDeclArg(EToken type);
00046         virtual void fncDecl();
00047         virtual void fncDefInit(EToken type, Token id);
00048         virtual void fncDefArg(EToken type, Token id);
00049         virtual void fncDefVar(EToken type, Token id);
00050         virtual void fncDefBody();
00051         virtual void fncDef();
00052         virtual void assign(Token token);
00053         virtual void ifEnter(Token token);
00054         virtual void ifElse();
00055         virtual void ifLeave();
00056         virtual void whileInit(Token token);
00057         virtual void whileEnter();
00058         virtual void whileLeave();
00059         virtual void pushToken(Token token);
00060         virtual void evalUnOp(Token token);
00061         virtual void evalBinOp(Token token);
00062         virtual void fncCall(Token id, int argsToPop, bool pushResult);
00063         virtual void fncCallPrint(Token id, EToken valType);
00064     private:
00065         Vm              *vm_;                           
00066         bool            hasError_;                      
00067         FncDeclaration  *fncDecl_;                      
00068         FncDefinition   *fncDef_;                       
00069         CmdFactory      cmdFactory_;                    
00070 
00071         typedef STD_PAIR(Token, PCmdList)   TBlock;
00072         typedef STD_STACK(TBlock)           TBlockStack;
00073         TBlockStack     blockStack_;                    
00074 
00075         typedef STD_STACK(Value::VType)     TTypeStack;
00076         TTypeStack      typeStack_;                     
00077 
00078         PVar createVar(EToken type, Token id);          
00079         bool appendCmd(PCmd);                           
00080         bool chkBlockStack();                           
00081         void pushTypeToStack(Value::VType);             
00082         Value::VType popTypeFromStack(const Token &);   
00083         void chkTypeOnTop(Value::VType type, const Token &);    
00084 };
00085 
00086 // /////////////////////////////////////////////////////////////////////////////
00087 // BuilderFactory implementation
00088 IBuilder* BuilderFactory::createBuilder(Vm *vm) {
00089     return new Builder(vm);
00090 }
00091 
00092 // /////////////////////////////////////////////////////////////////////////////
00093 // Builder implementation
00094 Builder::Builder(Vm *vm):
00095     vm_(vm),
00096     hasError_(false),
00097     fncDecl_(0),
00098     fncDef_(0),
00099     cmdFactory_(vm)
00100 {
00101 }
00102 
00103 Builder::~Builder() {
00104     delete fncDecl_;
00105     delete fncDef_;
00106 }
00107 
00108 void Builder::errorDetected() {
00109     hasError_ = true;
00110     if (fncDef_ && !blockStack_.empty())
00111         blockStack_.pop();
00112     delete fncDecl_;
00113     delete fncDef_;
00114     fncDecl_ = 0;
00115     fncDef_ = 0;
00116 }
00117 
00118 void Builder::glVar(EToken type, Token id) {
00119     PVar var = createVar(type, id);
00120     if (!var)
00121         return;
00122 
00123     VarSet &varSet = vm_ -> glVars;
00124     if (!varSet.add(var)) {
00125         hasError_ = true;
00126         std::cerr << Error(E_ERROR, vm_->fileName, "redefinition of global variable", id) << std::endl;
00127         PVar prev = varSet[id.text];
00128         if (prev && prev->defined.lineno)
00129             std::cerr << Error(E_NOTE, vm_->fileName, "previous definition was here", prev->defined.lineno) << std::endl;
00130     }
00131 }
00132 
00133 void Builder::fncDeclInit(EToken type, Token id) {
00134     if (fncDecl_) { 
00135         std::cerr << Error(E_WARNING, vm_->fileName, "unexpected declaration of function", id, true) << std::endl;
00136         return;
00137     }
00138 
00139     PVar var = createVar(type, id);
00140     if (!var)
00141         return;
00142 
00143     fncDecl_ = new FncDeclaration;
00144     fncDecl_ -> self = *var;
00145 }
00146 
00147 void Builder::fncDeclArg(EToken type) {
00148     if (!fncDecl_)
00149         return;
00150 
00151     PVar var = createVar(type, Token());
00152     if (!var)
00153         return;
00154 
00155     if (!fncDecl_->args.add(var))
00156         std::cerr << Error(E_WARNING, vm_->fileName, "failed to declare function argument", Token() ,true) << std::endl;
00157 }
00158 
00159 void Builder::fncDecl() {
00160     if (!fncDecl_)
00161         return;
00162 
00163     FncSet &fncSet = vm_ -> fncSet;
00164     if (!fncSet.addDeclaration(fncDecl_)) {
00165         hasError_ = true;
00166         const string &name = fncDecl_ -> self.name;
00167         std::cerr << Error(E_ERROR, vm_->fileName, "function declaration mismatch", fncDecl_->self.defined) << std::endl;
00168         FncDeclaration *prev = fncSet.getDeclaration(name);
00169         if (prev && prev->self.defined.lineno)
00170             std::cerr << Error(E_NOTE, vm_->fileName, "previous declaration was here", prev->self.defined) << std::endl;
00171         delete fncDecl_;
00172     }
00173 
00174     fncDecl_ = 0;
00175 }
00176 
00177 void Builder::fncDefInit(EToken type, Token id) {
00178     if (fncDef_) { 
00179         std::cerr << Error(E_WARNING, vm_->fileName, "unexpected definition of function", id, true) << std::endl;
00180         return;
00181     }
00182 
00183     PVar var = createVar(type, id);
00184     if (!var)
00185         return;
00186 
00187     fncDef_ = new FncDefinition(vm_);
00188     fncDef_ -> self = *var;
00189 }
00190 
00191 void Builder::fncDefArg(EToken type, Token id) {
00192     if (!fncDef_)
00193         return;
00194 
00195     if (id.text == fncDef_->self.name) {
00196         hasError_ = true;
00197         std::cerr << Error(E_ERROR, vm_->fileName, "function argument conflicts with function name", id) << std::endl;
00198         return;
00199     }
00200 
00201     PVar var = createVar(type, id);
00202     if (!var)
00203         return;
00204 
00205     PVar prev = fncDef_->args[id.text];
00206     if (prev) {
00207         hasError_ = true;
00208         std::cerr << Error(E_ERROR, vm_->fileName, "redefinition of function argument", id) << std::endl;
00209         if (prev->defined.lineno)
00210             std::cerr << Error(E_NOTE, vm_->fileName, "previous definition was here", prev->defined) << std::endl;
00211         return;
00212     }
00213 
00214     if (!fncDef_->args.add(var))
00215         std::cerr << Error(E_WARNING, vm_->fileName, "failed to define function argument", Token() ,true) << std::endl;
00216 }
00217 
00218 void Builder::fncDefVar(EToken type, Token id) {
00219     if (!fncDef_)
00220         return;
00221 
00222     const string &name = id.text;
00223     if (name == fncDef_->self.name) {
00224         hasError_ = true;
00225         std::cerr << Error(E_ERROR, vm_->fileName, "local variable conflicts with function name", id) << std::endl;
00226         return;
00227     }
00228 
00229     PVar arg = fncDef_->args[name];
00230     if (arg) {
00231         hasError_ = true;
00232         std::cerr << Error(E_ERROR, vm_->fileName, "local variable conflicts with function parameter", id) << std::endl;
00233         Token &tArg = arg->defined;
00234         if (tArg.lineno)
00235             std::cerr << Error(E_NOTE, vm_->fileName, "argument was defined here", tArg) << std::endl;
00236         return;
00237     }
00238 
00239     PVar var = createVar(type, id);
00240     if (!var)
00241         return;
00242 
00243     PVar prev = fncDef_->vars[name];
00244     if (prev) {
00245         hasError_ = true;
00246         std::cerr << Error(E_ERROR, vm_->fileName, "redefinition of local variable", id) << std::endl;
00247         if (prev->defined.lineno)
00248             std::cerr << Error(E_NOTE, vm_->fileName, "previous definition was here", prev->defined) << std::endl;
00249         return;
00250     }
00251 
00252     if (!fncDef_->vars.add(var))
00253         std::cerr << Error(E_WARNING, vm_->fileName, "failed to define local variable", Token() ,true) << std::endl;
00254 }
00255 
00256 void Builder::fncDefBody() {
00257     if (!fncDef_)
00258         return;
00259     const string &name = fncDef_ -> self.name;
00260     FncSet &fncSet = vm_ -> fncSet;
00261 
00262     FncDefinition *prev = fncSet.getDefinition(name);
00263     if (prev) {
00264         // fnc redefinition
00265         hasError_ = true;
00266         std::cerr << Error(E_ERROR, vm_->fileName, "redefinition of function", fncDef_->self.defined) << std::endl;
00267         Token &tPrev = prev->self.defined;
00268         if (tPrev.lineno)
00269             std::cerr << Error(E_NOTE, vm_->fileName, "previous definition was here", tPrev) << std::endl;
00270         delete fncDef_;
00271         fncDef_ = 0;
00272         return;
00273     }
00274 
00275     if (!fncSet.addDeclaration(new FncDeclaration(*fncDef_))) {
00276         // fnc decl/def mismatch
00277         hasError_ = true;
00278         std::cerr << Error(E_ERROR, vm_->fileName, "function declaration/definition mismatch", fncDef_->self.defined) << std::endl;
00279         FncDeclaration *prev = fncSet.getDeclaration(name);
00280         if (prev && prev->self.defined.lineno)
00281             std::cerr << Error(E_NOTE, vm_->fileName, "previous declaration was here", prev->self.defined) << std::endl;
00282         delete fncDef_;
00283         fncDef_ = 0;
00284         return;
00285     }
00286 
00287     // init BlockStack for function
00288     if (!blockStack_.empty())
00289         std::cerr << Error(E_WARNING, vm_->fileName, "BlockStack offset detected", fncDef_->self.defined, true) << std::endl;
00290     blockStack_.push(TBlock(fncDef_->self.defined, fncDef_->cmdList));
00291 }
00292 
00293 void Builder::fncDef() {
00294     if (!fncDef_)
00295         return;
00296 
00297     FncSet &fncSet = vm_ -> fncSet;
00298     if (!fncSet.addDefinition(fncDef_)) {
00299         hasError_ = true;
00300         std::cerr << Error(E_ERROR, vm_->fileName, "function definition failed", fncDef_->self.defined, true) << std::endl;
00301         delete fncDef_;
00302     }
00303 
00304     if (chkBlockStack()) {
00305         blockStack_.pop();
00306         if (!blockStack_.empty())
00307             std::cerr << Error(E_WARNING, vm_->fileName, "BlockStack offset detected", fncDef_->self.defined, true) << std::endl;
00308     }
00309     fncDef_ = 0;
00310 }
00311 
00312 void Builder::assign(Token token) {
00313     if (!fncDef_) {
00314         std::cerr << Error(E_WARNING, vm_->fileName, "assignement not within function definition", token, true) << std::endl;
00315         return;
00316     }
00317     Value::VType dstType;
00318     if (appendCmd (cmdFactory_.createAssign(token, fncDef_, dstType)))
00319         chkTypeOnTop(dstType, token);
00320 }
00321 
00322 void Builder::ifEnter(Token token) {
00323     PCmdList ifList(new CmdList);
00324     blockStack_.push(TBlock(token, ifList));
00325     chkTypeOnTop(Value::V_BOOL, token);
00326 }
00327 
00328 void Builder::ifElse() {
00329     if (!chkBlockStack())
00330         return;
00331     const TBlock &top = blockStack_.top();
00332 
00333     PCmdList elseList(new CmdList);
00334     blockStack_.push(TBlock(top.first, elseList));
00335 }
00336 
00337 void Builder::ifLeave() {
00338     // pop "else list" from stack
00339     if (!chkBlockStack())
00340         return;
00341     TBlock elseBlock = blockStack_.top();
00342     blockStack_.pop();
00343 
00344     // pop "if list" from stack
00345     if (!chkBlockStack())
00346         return;
00347     TBlock ifBlock = blockStack_.top();
00348     blockStack_.pop();
00349 
00350     // push "if command" to current list
00351     appendCmd(cmdFactory_.createIf(
00352                 ifBlock.first,                          // token "if"
00353                 ifBlock.second,                         // command list for positive branch
00354                 elseBlock.second));                     // command list for negative branch
00355 }
00356 
00357 void Builder::whileInit(Token token) {
00358     PCmdList exprList(new CmdList);
00359     blockStack_.push(TBlock(token, exprList));
00360 }
00361 
00362 void Builder::whileEnter() {
00363     if (!chkBlockStack())
00364         return;
00365     const TBlock &top = blockStack_.top();
00366 
00367     PCmdList statList(new CmdList);
00368     blockStack_.push(TBlock(top.first, statList));
00369 }
00370 
00371 void Builder::whileLeave() {
00372     // pop "stat list" from stack
00373     if (!chkBlockStack())
00374         return;
00375     TBlock statBlock = blockStack_.top();
00376     blockStack_.pop();
00377 
00378     // pop "expr list" from stack
00379     if (!chkBlockStack())
00380         return;
00381     TBlock exprBlock = blockStack_.top();
00382     blockStack_.pop();
00383 
00384     // push "while command" to current list
00385     appendCmd(cmdFactory_.createWhile(
00386                 exprBlock.first,                         // token "while"
00387                 exprBlock.second,                        // command list to evaluate "while" condition
00388                 statBlock.second));                      // block of commands for "while" statement
00389 }
00390 
00391 void Builder::pushToken(Token token) {
00392     if (!fncDef_) {
00393         std::cerr << Error(E_WARNING, vm_->fileName, "pushToken not within function definition", token, true) << std::endl;
00394         return;
00395     }
00396     Value::VType dstType;
00397     appendCmd(cmdFactory_.createPush(token, fncDef_, dstType));
00398     pushTypeToStack(dstType);
00399 }
00400 
00401 void Builder::evalUnOp(Token token) {
00402     Value::VType vt = popTypeFromStack(token);
00403     if ((token.type == ETOKEN_KW_NOT && vt != Value::V_BOOL)
00404             || (token.type == ETOKEN_OP_MINUS && (vt != Value::V_INT
00405                     && vt != Value::V_DOUBLE)))
00406     {
00407         hasError_ = true;
00408         std::cerr << Error(E_ERROR, vm_->fileName, "type not allowed for unary ", token) << token << std::endl;
00409         std::cerr << Error(E_NOTE, vm_->fileName, "expression type: ") << vt << std::endl;
00410     }
00411     appendCmd(cmdFactory_.createUnary(token));
00412     pushTypeToStack(vt);
00413 }
00414 
00415 void Builder::evalBinOp(Token token) {
00416     Value::VType t2 = popTypeFromStack(token);
00417     Value::VType t1 = popTypeFromStack(token);
00418     Value::VType dstType;
00419     if (!appendCmd(cmdFactory_.createBinary(token, t1, t2, dstType))
00420                 || dstType == Value::V_NULL)
00421     {
00422         hasError_ = true;
00423         std::cerr << Error(E_ERROR, vm_->fileName, "type combination is not valid for binary ", token) << token << std::endl;
00424         std::cerr << Error(E_NOTE, vm_->fileName, "type of operand 1: ") << t1 << std::endl;
00425         std::cerr << Error(E_NOTE, vm_->fileName, "type of operand 2: ") << t2 << std::endl;
00426     }
00427     pushTypeToStack(dstType);
00428 }
00429 
00430 void Builder::fncCall(Token id, int argsToPop, bool pushResult) {
00431     const string &name = id.text;
00432     if (name == "print") {
00433         std::cerr << Error(E_ERROR, vm_->fileName, "invalid use of reserved function name", id) << std::endl;
00434         hasError_ = true;
00435         return;
00436     }
00437 
00438     FncDeclaration *fnc = vm_->fncSet.getDeclaration(name);
00439     if (!fnc) {
00440         std::cerr << Error(E_ERROR, vm_->fileName, "call of undeclared function", id) << std::endl;
00441         hasError_ = true;
00442         return;
00443     }
00444     unsigned argCnt = fnc->args.size();
00445     if (argCnt != static_cast<unsigned>(argsToPop)) {
00446         std::cerr << Error(E_ERROR, vm_->fileName, "arguments count mismatch in function call", id) << std::endl;
00447         Token &t = fnc->self.defined;
00448         if (t.lineno)
00449             std::cerr << Error(E_NOTE, vm_->fileName, "function is declared here", t) << std::endl;
00450         hasError_ = true;
00451         return;
00452     }
00453     for (unsigned i = 0; i < argCnt; i++) {
00454         unsigned n = argCnt - i - 1;
00455         Value::VType argType = fnc->args[n]->value.type;
00456         chkTypeOnTop(argType, id);
00457     }
00458 
00459     // check for built-in input{int|double|string}() function
00460     bool iInt =     name == "inputint";
00461     bool iDouble =  name == "inputdouble";
00462     bool iString =  name == "inputstring";
00463     if (!pushResult
00464             && (iInt || iDouble || iString))
00465         std::cerr << Error(E_WARNING, vm_->fileName, "return value of input function is not used", id) << std::endl;
00466 
00467     if (iInt)
00468         appendCmd(cmdFactory_.createInput(id, Value::V_INT, pushResult));
00469     else if (iDouble)
00470         appendCmd(cmdFactory_.createInput(id, Value::V_DOUBLE, pushResult));
00471     else if (iString)
00472         appendCmd(cmdFactory_.createInput(id, Value::V_STRING, pushResult));
00473     else {
00474         // ordinary function call
00475         vm_->calleeSet.add(name, id);
00476         appendCmd(cmdFactory_.createCall(id, argsToPop, pushResult));
00477     }
00478     if (pushResult)
00479         pushTypeToStack(fnc->self.value.type);
00480 }
00481 
00482 void Builder::fncCallPrint(Token id, EToken valType) {
00483     Value::VType srcType;
00484     if (appendCmd(cmdFactory_.createPrint(id, valType, srcType)))
00485         chkTypeOnTop(srcType, id);
00486 }
00487 
00488 PVar Builder::createVar(EToken type, Token id) {
00489     PVar var;
00490     PValue val(new Value);
00491     switch (type) {
00492         case ETOKEN_KW_VOID:    val -> type = Value::V_NULL;    break;
00493         case ETOKEN_KW_INT:     val -> type = Value::V_INT;     break;
00494         case ETOKEN_KW_DOUBLE:  val -> type = Value::V_DOUBLE;  break;
00495         case ETOKEN_KW_STRING:  val -> type = Value::V_STRING;  break;
00496         default:
00497             std::cerr << Error(E_WARNING, vm_->fileName, "unhandled variable type", id, true) << std::endl;
00498             return var;
00499     }
00500     var.reset(new Var);
00501     var -> name = id.text;
00502     var -> value = *val;
00503     var -> defined = id;
00504     return var;
00505 }
00506 
00507 bool Builder::appendCmd(PCmd cmd) {
00508     if (!cmd){
00509         hasError_ = true;
00510         return false;
00511     }
00512     if (!chkBlockStack())
00513         return false;
00514     TBlock &top = blockStack_.top();
00515     PCmdList &list = top.second;
00516     list -> add(cmd);
00517     return true;
00518 }
00519 bool Builder::chkBlockStack() {
00520     if (blockStack_.empty()) {
00521         std::cerr << Error(E_WARNING, vm_->fileName, "BlockStack underflow detected", fncDef_->self.defined, true) << std::endl;
00522         return false;
00523     }
00524     return true;
00525 }
00526 void Builder::pushTypeToStack(Value::VType type) {
00527 #if DEBUG_TRACE_TYPESTACK
00528     std::cerr << Color(C_LIGHT_CYAN) << "TypeStack" << Color(C_NO_COLOR)
00529         << " <-- " << type << std::endl;
00530 #endif
00531     typeStack_.push(type);
00532 }
00533 Value::VType Builder::popTypeFromStack(const Token &t) {
00534     Value::VType type = Value::V_NULL;
00535     if (typeStack_.empty()) {
00536         std::cerr << Error(E_WARNING, vm_->fileName, "TypeStack underflow detected", t, true) << std::endl;
00537     } else {
00538         type = typeStack_.top();
00539         typeStack_.pop();
00540 #if DEBUG_TRACE_TYPESTACK
00541     std::cerr << Color(C_LIGHT_CYAN) << "TypeStack" << Color(C_NO_COLOR)
00542         << " --> " << type << std::endl;
00543 #endif
00544     }
00545     return type;
00546 }
00547 void Builder::chkTypeOnTop(Value::VType dstType, const Token &t) {
00548     Value::VType srcType = popTypeFromStack(t);
00549     if (srcType != dstType) {
00550         hasError_ = true;
00551         std::cerr << Error(E_ERROR, vm_->fileName, "type mismatch", t) << std::endl;
00552         std::cerr << Error(E_NOTE, vm_->fileName, " expression type: ") << srcType << std::endl;
00553         std::cerr << Error(E_NOTE, vm_->fileName, "destination type: ") << dstType << std::endl;
00554     }
00555 }
00556 
00557 // /////////////////////////////////////////////////////////////////////////////
00558 // FncFactory implementation
00559 struct FncFactory::Private {
00560     Vm      *const vm;
00561     Private(Vm *vm_):
00562         vm(vm_)
00563     {
00564     }
00565     static bool addDefinition(Vm *, FncDefinition *);
00566     static FncDefinition* createFnc(Vm *, string, PValue);
00567 };
00568 FncFactory::FncFactory(Vm *vm):
00569     d(new Private(vm))
00570 {
00571 }
00572 FncFactory::~FncFactory() {
00573     delete d;
00574 }
00575 bool FncFactory::initVm(Vm *vm) {
00576     FncFactory *factory = new FncFactory(vm);
00577 
00578     // declare main
00579     vm->calleeSet.add("main", Token());
00580     FncDeclaration *declMain = factory -> createMainDecl();
00581     bool bOk = declMain;
00582     bOk &= vm->fncSet.addDeclaration(declMain);
00583 
00584     // define built-ins
00585     bOk &= Private::addDefinition (vm, factory -> createPrint());
00586     bOk &= Private::addDefinition (vm, factory -> createInputString());
00587     bOk &= Private::addDefinition (vm, factory -> createInputInt());
00588     bOk &= Private::addDefinition (vm, factory -> createInputDouble());
00589 
00590     delete factory;
00591     return bOk;
00592 }
00593 bool FncFactory::Private::addDefinition(Vm *vm, FncDefinition *fnc) {
00594     if (!vm || !fnc)
00595         return false;
00596 
00597     if (!vm->fncSet.addDefinition(fnc))
00598         return false;
00599 
00600     vm->calleeSet.add(fnc->self.name, Token());
00601     return true;
00602 }
00603 
00604 FncDefinition* FncFactory::Private::createFnc(Vm *vm, string name, PValue val) {
00605     PVar var(new Var);
00606     var -> name = name;
00607     var -> value = *val;
00608 
00609     FncDefinition *fnc = new FncDefinition(vm);
00610     fnc -> self = *var;
00611     return fnc;
00612 }
00613 
00614 FncDeclaration* FncFactory::createMainDecl() {
00615     PVar var(new Var);
00616     var -> name = "main";
00617     var -> value = *(ValueFactory::create());
00618 
00619     FncDeclaration *mainDecl = new FncDeclaration;
00620     mainDecl -> self = *var;
00621     return mainDecl;
00622 }
00623 
00624 FncDefinition* FncFactory::createPrint() {
00625     return Private::createFnc(d->vm, "print",
00626             ValueFactory::create(false));
00627 }
00628 
00629 FncDefinition* FncFactory::createInputString() {
00630     return Private::createFnc(d->vm, "inputstring",
00631             ValueFactory::create(string()));
00632 }
00633 
00634 FncDefinition* FncFactory::createInputInt() {
00635     return Private::createFnc(d->vm, "inputint",
00636             ValueFactory::create(0));
00637 }
00638 
00639 FncDefinition* FncFactory::createInputDouble() {
00640     return Private::createFnc(d->vm, "inputdouble",
00641             ValueFactory::create(0.0));
00642 }
00643 

Generated on Sat Jul 4 18:32:59 2009 for vyp08 (compiler and interpreter of VYP08 language) by  doxygen 1.5.4