/***** Autogenerated from runsystem.in; changes will be overwritten *****/

#line 1 "./runtimebase.in"
/*****
* runtimebase.in
* Andy Hammerlindl  2009/07/28
*
* Common declarations needed for all code-generating .in files.
*
*****/


#line 1 "./runsystem.in"
/*****
* runsystem.in
*
* Runtime functions for system operations.
*
*****/

#line 23 "./runtimebase.in"
#include "stack.h"
#include "types.h"
#include "builtin.h"
#include "entry.h"
#include "errormsg.h"
#include "array.h"
#include "triple.h"
#include "callable.h"
#include "opsymbols.h"

using vm::stack;
using vm::error;
using vm::array;
using vm::read;
using vm::callable;
using types::formal;
using types::function;
using camp::triple;

#define PRIMITIVE(name,Name,asyName) using types::prim##Name;
#include <primitives.h>
#undef PRIMITIVE

void unused(void *);

namespace run {
typedef double real;

array *copyArray(array *a);
array *copyArray2(array *a);
array *copyArray3(array *a);

double *copyTripleArray2Components(array *a, size_t &N,
                                  GCPlacement placement=NoGC);
triple *copyTripleArray2C(array *a, size_t &N,
                         GCPlacement placement=NoGC);
}

function *realRealFunction();

#define CURRENTPEN processData().currentpen

#line 12 "runsystem.in"
#include "asyprocess.h"
#include "stack.h"
#include "locate.h"

using namespace camp;
using namespace settings;
using vm::bpinfo;
using vm::bplist;
using vm::getPos;
using vm::Default;
using vm::nullfunc;
using vm::item;
using absyntax::runnable;

typedef callable callableBp;

namespace run {
extern string emptystring;
}

function *voidFunction()
{
 return new function(primVoid());
}

function *breakpointFunction()
{
 return new function(primString(),primString(),primInt(),primInt(),
                     primCode());
}

void clear(string file, Int line, bool warn=false)
{
 bpinfo bp(file,line);
 for(mem::list<bpinfo>::iterator p=bplist.begin(); p != bplist.end(); ++p) {
   if(*p == bp) {
     cout << "cleared breakpoint at " << file << ": " << line << endl;
     bplist.remove(bp);
     return;
   }
 }
 if(warn)
   cout << "No such breakpoint at "  << file << ": " << line << endl;
}

namespace run {
void breakpoint(stack *Stack, runnable *r)
{
 callable *atBreakpointFunction=processData().atBreakpointFunction;
 if(atBreakpointFunction &&
    !nullfunc::instance()->compare(atBreakpointFunction)) {
   position curPos=getPos();
   Stack->push<string>(curPos.filename());
   Stack->push<Int>((Int) curPos.Line());
   Stack->push<Int>((Int) curPos.Column());
   Stack->push(r ? r : vm::Default);
   atBreakpointFunction->call(Stack); // returns a string
 } else Stack->push<string>("");
}
}

string convertname(string name, const string& format)
{
 if(name.empty())
   return buildname(outname(),format,"");
 name=outpath(name);
 return format.empty() ? name : format+":"+name;
}

namespace run {
void purge(Int divisor=0)
{
#ifdef USEGC
 if(divisor > 0) GC_set_free_space_divisor((GC_word) divisor);
 GC_gcollect();
#endif
}

void updateFunction(stack *Stack)
{
 callable *atUpdateFunction=processData().atUpdateFunction;
 if(atUpdateFunction && !nullfunc::instance()->compare(atUpdateFunction))
   atUpdateFunction->call(Stack);
}

void exitFunction(stack *Stack)
{
 callable *atExitFunction=processData().atExitFunction;
 if(atExitFunction && !nullfunc::instance()->compare(atExitFunction))
   atExitFunction->call(Stack);
}
}

// Autogenerated routines:


#ifndef NOSYM
#include "runsystem.symbols.h"

#endif
namespace run {
#line 107 "./runsystem.in"
// string outname();
void gen_runsystem0(stack *Stack)
{
#line 108 "./runsystem.in"
 {Stack->push<string>(outname()); return;}
}

#line 112 "./runsystem.in"
// void atupdate(callable *f);
void gen_runsystem1(stack *Stack)
{
 callable * f=vm::pop<callable *>(Stack);
#line 113 "./runsystem.in"
 processData().atUpdateFunction=f;
}

#line 117 "./runsystem.in"
// callable* atupdate();
void gen_runsystem2(stack *Stack)
{
#line 118 "./runsystem.in"
 {Stack->push<callable*>(processData().atUpdateFunction); return;}
}

#line 122 "./runsystem.in"
// void atexit(callable *f);
void gen_runsystem3(stack *Stack)
{
 callable * f=vm::pop<callable *>(Stack);
#line 123 "./runsystem.in"
 processData().atExitFunction=f;
}

#line 127 "./runsystem.in"
// callable* atexit();
void gen_runsystem4(stack *Stack)
{
#line 128 "./runsystem.in"
 {Stack->push<callable*>(processData().atExitFunction); return;}
}

#line 132 "./runsystem.in"
// void atbreakpoint(callableBp *f);
void gen_runsystem5(stack *Stack)
{
 callableBp * f=vm::pop<callableBp *>(Stack);
#line 133 "./runsystem.in"
 processData().atBreakpointFunction=f;
}

#line 137 "./runsystem.in"
// void breakpoint(runnable *s=NULL);
void gen_runsystem6(stack *Stack)
{
 runnable * s=vm::pop<runnable *>(Stack,NULL);
#line 138 "./runsystem.in"
 breakpoint(Stack,s);
}

#line 142 "./runsystem.in"
// string locatefile(string file, bool full=true);
void gen_runsystem7(stack *Stack)
{
 bool full=vm::pop<bool>(Stack,true);
 string file=vm::pop<string>(Stack);
#line 143 "./runsystem.in"
 {Stack->push<string>(locateFile(file,full)); return;}
}

#line 147 "./runsystem.in"
// void stop(string file, Int line, runnable *s=NULL);
void gen_runsystem8(stack *Stack)
{
 runnable * s=vm::pop<runnable *>(Stack,NULL);
 Int line=vm::pop<Int>(Stack);
 string file=vm::pop<string>(Stack);
#line 148 "./runsystem.in"
 file=locateFile(file);
 clear(file,line);
 cout << "setting breakpoint at " << file << ": " << line << endl;
 bplist.push_back(bpinfo(file,line,s));
}

#line 155 "./runsystem.in"
// void breakpoints();
void gen_runsystem9(stack *)
{
#line 156 "./runsystem.in"
 for(mem::list<bpinfo>::iterator p=bplist.begin(); p != bplist.end(); ++p)
   cout << p->f.name() << ": " << p->f.line() << endl;
}

#line 161 "./runsystem.in"
// void clear(string file, Int line);
void gen_runsystem10(stack *Stack)
{
 Int line=vm::pop<Int>(Stack);
 string file=vm::pop<string>(Stack);
#line 162 "./runsystem.in"
 file=locateFile(file);
 clear(file,line,true);
}

#line 167 "./runsystem.in"
// void clear();
void gen_runsystem11(stack *)
{
#line 168 "./runsystem.in"
 bplist.clear();
}

#line 172 "./runsystem.in"
// void warn(string s);
void gen_runsystem12(stack *Stack)
{
 string s=vm::pop<string>(Stack);
#line 173 "./runsystem.in"
 Warn(s);
}

#line 177 "./runsystem.in"
// void nowarn(string s);
void gen_runsystem13(stack *Stack)
{
 string s=vm::pop<string>(Stack);
#line 178 "./runsystem.in"
 noWarn(s);
}

#line 182 "./runsystem.in"
// void warning(string s, string t, bool position=false);
void gen_runsystem14(stack *Stack)
{
 bool position=vm::pop<bool>(Stack,false);
 string t=vm::pop<string>(Stack);
 string s=vm::pop<string>(Stack);
#line 183 "./runsystem.in"
 if(settings::warn(s)) {
   em.warning(position ? getPos() : nullPos,s);
   em << t;
   em.sync(true);
 }
}

// Strip directory from string
#line 192 "./runsystem.in"
// string stripdirectory(string *s);
void gen_runsystem15(stack *Stack)
{
 string * s=vm::pop<string *>(Stack);
#line 193 "./runsystem.in"
 {Stack->push<string>(stripDir(*s)); return;}
}

// Strip directory from string
#line 198 "./runsystem.in"
// string stripfile(string *s);
void gen_runsystem16(stack *Stack)
{
 string * s=vm::pop<string *>(Stack);
#line 199 "./runsystem.in"
 {Stack->push<string>(stripFile(*s)); return;}
}

// Strip file extension from string
#line 204 "./runsystem.in"
// string stripextension(string *s);
void gen_runsystem17(stack *Stack)
{
 string * s=vm::pop<string *>(Stack);
#line 205 "./runsystem.in"
 {Stack->push<string>(stripExt(*s)); return;}
}

// Call ImageMagick convert.
#line 210 "./runsystem.in"
// Int convert(string args=emptystring, string file=emptystring,            string format=emptystring);
void gen_runsystem18(stack *Stack)
{
 string format=vm::pop<string>(Stack,emptystring);
 string file=vm::pop<string>(Stack,emptystring);
 string args=vm::pop<string>(Stack,emptystring);
#line 212 "./runsystem.in"
 string name=convertname(file,format);
 mem::vector<string> cmd;
 string s=getSetting<string>("convert");
 cmd.push_back(s);
 push_split(cmd,args);
 cmd.push_back(name);
 bool quiet=verbose <= 1;

 char *oldPath=NULL;
 string dir=stripFile(outname());
 if(!dir.empty()) {
   oldPath=getPath();
   setPath(dir.c_str());
 }
 Int ret=System(cmd,quiet ? 1 : 0,true,"convert",
                "your ImageMagick convert utility");
 if(oldPath != NULL)
   setPath(oldPath);

 if(ret == 0 && verbose > 0)
   cout << "Wrote " << (file.empty() ? name : file) << endl;

 {Stack->push<Int>(ret); return;}
}

// Call ImageMagick animate.
#line 239 "./runsystem.in"
// Int animate(string args=emptystring, string file=emptystring,            string format=emptystring);
void gen_runsystem19(stack *Stack)
{
 string format=vm::pop<string>(Stack,emptystring);
 string file=vm::pop<string>(Stack,emptystring);
 string args=vm::pop<string>(Stack,emptystring);
#line 241 "./runsystem.in"
 string name=convertname(file,format);
 if(view()) {
   mem::vector<string> cmd;
   string s=getSetting<string>("animate");
   cmd.push_back(s);
   if(s == "magick")
     cmd.push_back("animate");
   push_split(cmd,args);
   cmd.push_back(name);
   {Stack->push<Int>(System(cmd,0,false,"animate","your animated GIF viewer")); return;}
 }
 {Stack->push<Int>(0); return;}
}

#line 256 "./runsystem.in"
// void purge(Int divisor=0);
void gen_runsystem20(stack *Stack)
{
 Int divisor=vm::pop<Int>(Stack,0);
#line 257 "./runsystem.in"
 purge(divisor);
}

} // namespace run

namespace trans {

void gen_runsystem_venv(venv &ve)
{
#line 107 "./runsystem.in"
 addFunc(ve, run::gen_runsystem0, primString(), SYM(outname));
#line 112 "./runsystem.in"
 addFunc(ve, run::gen_runsystem1, primVoid(), SYM(atupdate), formal(voidFunction(), SYM(f), false, false));
#line 117 "./runsystem.in"
 addFunc(ve, run::gen_runsystem2, voidFunction(), SYM(atupdate));
#line 122 "./runsystem.in"
 addFunc(ve, run::gen_runsystem3, primVoid(), SYM(atexit), formal(voidFunction(), SYM(f), false, false));
#line 127 "./runsystem.in"
 addFunc(ve, run::gen_runsystem4, voidFunction(), SYM(atexit));
#line 132 "./runsystem.in"
 addFunc(ve, run::gen_runsystem5, primVoid(), SYM(atbreakpoint), formal(breakpointFunction(), SYM(f), false, false));
#line 137 "./runsystem.in"
 addFunc(ve, run::gen_runsystem6, primVoid(), SYM(breakpoint), formal(primCode(), SYM(s), true, false));
#line 142 "./runsystem.in"
 addFunc(ve, run::gen_runsystem7, primString(), SYM(locatefile), formal(primString(), SYM(file), false, false), formal(primBoolean(), SYM(full), true, false));
#line 147 "./runsystem.in"
 addFunc(ve, run::gen_runsystem8, primVoid(), SYM(stop), formal(primString(), SYM(file), false, false), formal(primInt(), SYM(line), false, false), formal(primCode(), SYM(s), true, false));
#line 155 "./runsystem.in"
 addFunc(ve, run::gen_runsystem9, primVoid(), SYM(breakpoints));
#line 161 "./runsystem.in"
 addFunc(ve, run::gen_runsystem10, primVoid(), SYM(clear), formal(primString(), SYM(file), false, false), formal(primInt(), SYM(line), false, false));
#line 167 "./runsystem.in"
 addFunc(ve, run::gen_runsystem11, primVoid(), SYM(clear));
#line 172 "./runsystem.in"
 addFunc(ve, run::gen_runsystem12, primVoid(), SYM(warn), formal(primString(), SYM(s), false, false));
#line 177 "./runsystem.in"
 addFunc(ve, run::gen_runsystem13, primVoid(), SYM(nowarn), formal(primString(), SYM(s), false, false));
#line 182 "./runsystem.in"
 addFunc(ve, run::gen_runsystem14, primVoid(), SYM(warning), formal(primString(), SYM(s), false, false), formal(primString(), SYM(t), false, false), formal(primBoolean(), SYM(position), true, false));
#line 191 "./runsystem.in"
 addFunc(ve, run::gen_runsystem15, primString(), SYM(stripdirectory), formal(primString(), SYM(s), false, false));
#line 197 "./runsystem.in"
 addFunc(ve, run::gen_runsystem16, primString(), SYM(stripfile), formal(primString(), SYM(s), false, false));
#line 203 "./runsystem.in"
 addFunc(ve, run::gen_runsystem17, primString(), SYM(stripextension), formal(primString(), SYM(s), false, false));
#line 209 "./runsystem.in"
 addFunc(ve, run::gen_runsystem18, primInt(), SYM(convert), formal(primString(), SYM(args), true, false), formal(primString(), SYM(file), true, false), formal(primString(), SYM(format), true, false));
#line 238 "./runsystem.in"
 addFunc(ve, run::gen_runsystem19, primInt(), SYM(animate), formal(primString(), SYM(args), true, false), formal(primString(), SYM(file), true, false), formal(primString(), SYM(format), true, false));
#line 256 "./runsystem.in"
 addFunc(ve, run::gen_runsystem20, primVoid(), SYM(purge), formal(primInt(), SYM(divisor), true, false));
}

} // namespace trans