00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <stdio.h>
00024 #include <stdlib.h>
00025 #include <string.h>
00026
00027 #include "collector.h"
00028 #include "value.h"
00029 #include "object.h"
00030 #include "types.h"
00031 #include "interpreter.h"
00032
00033 using namespace KJS;
00034
00035 class TestFunctionImp : public ObjectImp {
00036 public:
00037 TestFunctionImp(int i, int length);
00038 virtual bool implementsCall() const { return true; }
00039 virtual Value call(ExecState *exec, Object &thisObj, const List &args);
00040
00041 enum { Print, Debug, Quit, GC };
00042
00043 private:
00044 int id;
00045 };
00046
00047 TestFunctionImp::TestFunctionImp(int i, int length) : ObjectImp(), id(i)
00048 {
00049 putDirect(lengthPropertyName,length,DontDelete|ReadOnly|DontEnum);
00050 }
00051
00052 Value TestFunctionImp::call(ExecState *exec, Object &, const List &args)
00053 {
00054 switch (id) {
00055 case Print:
00056 case Debug:
00057 fprintf(stderr,"--> %s\n",args[0].toString(exec).ascii());
00058 return Undefined();
00059 case GC:
00060 Interpreter::lock();
00061 Collector::collect();
00062 Interpreter::unlock();
00063 return Undefined();
00064 case Quit:
00065 exit(0);
00066 return Undefined();
00067 default:
00068 break;
00069 }
00070
00071 return Undefined();
00072 }
00073
00074 class VersionFunctionImp : public ObjectImp {
00075 public:
00076 VersionFunctionImp() : ObjectImp() {}
00077 virtual bool implementsCall() const { return true; }
00078 virtual Value call(ExecState *exec, Object &thisObj, const List &args);
00079 };
00080
00081 Value VersionFunctionImp::call(ExecState *, Object &, const List &)
00082 {
00083
00084
00085 return Undefined();
00086 }
00087
00088 class GlobalImp : public ObjectImp {
00089 public:
00090 virtual UString className() const { return "global"; }
00091 };
00092
00093 int main(int argc, char **argv)
00094 {
00095
00096 if (argc < 2) {
00097 fprintf(stderr, "You have to specify at least one filename\n");
00098 return -1;
00099 }
00100
00101 bool ret = true;
00102 {
00103 Object global(new GlobalImp());
00104
00105
00106 Interpreter interp(global);
00107
00108 global.put(interp.globalExec(), "debug", Object(new TestFunctionImp(TestFunctionImp::Debug,1)));
00109
00110 global.put(interp.globalExec(), "print", Object(new TestFunctionImp(TestFunctionImp::Print,1)));
00111
00112 global.put(interp.globalExec(), "quit", Object(new TestFunctionImp(TestFunctionImp::Quit,0)));
00113
00114 global.put(interp.globalExec(), "gc", Object(new TestFunctionImp(TestFunctionImp::GC, 0)));
00115
00116 global.put(interp.globalExec(), "version", Object(new VersionFunctionImp()));
00117
00118 for (int i = 1; i < argc; i++) {
00119 int code_len = 0;
00120 int code_alloc = 1024;
00121 char *code = (char*)malloc(code_alloc);
00122
00123 const char *file = argv[i];
00124 if (strcmp(file, "-f") == 0)
00125 continue;
00126 FILE *f = fopen(file, "r");
00127 if (!f) {
00128 fprintf(stderr, "Error opening %s.\n", file);
00129 return 2;
00130 }
00131
00132 while (!feof(f) && !ferror(f)) {
00133 size_t len = fread(code+code_len,1,code_alloc-code_len,f);
00134 code_len += len;
00135 if (code_len >= code_alloc) {
00136 code_alloc *= 2;
00137 code = (char*)realloc(code,code_alloc);
00138 }
00139 }
00140 code = (char*)realloc(code,code_len+1);
00141 code[code_len] = '\0';
00142
00143
00144 Completion comp(interp.evaluate(code));
00145
00146 fclose(f);
00147
00148 if (comp.complType() == Throw) {
00149 ExecState *exec = interp.globalExec();
00150 Value exVal = comp.value();
00151 char *msg = exVal.toString(exec).ascii();
00152 int lineno = -1;
00153 if (exVal.type() == ObjectType) {
00154 Value lineVal = Object::dynamicCast(exVal).get(exec,"line");
00155 if (lineVal.type() == NumberType)
00156 lineno = int(lineVal.toNumber(exec));
00157 }
00158 if (lineno != -1)
00159 fprintf(stderr,"Exception, line %d: %s\n",lineno,msg);
00160 else
00161 fprintf(stderr,"Exception: %s\n",msg);
00162 ret = false;
00163 }
00164 else if (comp.complType() == ReturnValue) {
00165 char *msg = comp.value().toString(interp.globalExec()).ascii();
00166 fprintf(stderr,"Return value: %s\n",msg);
00167 }
00168
00169 free(code);
00170 }
00171
00172 }
00173
00174 if (ret)
00175 fprintf(stderr, "OK.\n");
00176
00177 #ifdef KJS_DEBUG_MEM
00178 Interpreter::finalCheck();
00179 #endif
00180 return ret ? 0 : 3;
00181 }