src/main.cpp
author David Anderson <dvander@alliedmods.net>
Sun Aug 05 02:17:40 2012 -0700 (2012-08-05)
changeset 163 efc3f91dbe42
parent 162 c9fa93ce2f1f
child 174 e718b56aba78
permissions -rw-r--r--
Added printing natives.
     1 /* vim: set ts=4 sw=4 tw=99 et:
     2  *
     3  * Copyright (C) 2012 David Anderson
     4  *
     5  * This file is part of SourcePawn.
     6  *
     7  * SourcePawn is free software: you can redistribute it and/or modify it under
     8  * the terms of the GNU General Public License as published by the Free
     9  * Software Foundation, either version 3 of the License, or (at your option)
    10  * any later version.
    11  * 
    12  * SourcePawn is distributed in the hope that it will be useful, but WITHOUT ANY
    13  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    14  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
    15  *
    16  * You should have received a copy of the GNU General Public License along with
    17  * SourcePawn. If not, see http://www.gnu.org/licenses/.
    18  */
    19 #include <stdio.h>
    20 #include <stdlib.h>
    21 #include <string.h>
    22 #include "../include/keima.h"
    23 
    24 using namespace Ke;
    25 
    26 class MessageReporter : public IMessageReporter
    27 {
    28   public:
    29     void onOutOfMemory() {
    30         fprintf(stderr, "Out of memory!\n");
    31     }
    32     void onUncaughtException(const char *message) {
    33         fprintf(stderr, "Uncaught exception: %s\n", message);
    34 
    35         IStackFrameIterator *iter = Keima::NewStackFrameIterator();
    36         unsigned index = 0;
    37         while (!iter->done()) {
    38             fprintf(stderr, "[%d] %s (%s line %d)\n",
    39                     index,
    40                     iter->function(),
    41                     iter->source(),
    42                     iter->lineNumber());
    43             iter->prev();
    44             index++;
    45         }
    46     }
    47     virtual void beginCompilationErrors(const char *file) {
    48         fprintf(stderr, "\nDisplaying compilation errors for \"%s\"\n", file);
    49     }
    50     virtual void reportCompilationError(const char *message, unsigned line, unsigned col) {
    51         fprintf(stderr, "  line %d, col %d: %s\n", line, col, message);
    52     }
    53     virtual void endCompilationErrors() {
    54     }
    55 } s_Reporter;
    56 
    57 intptr_t PrintFloat(void *blah, intptr_t *params)
    58 {
    59     fprintf(stdout, "%f", *reinterpret_cast<float *>(&params[1]));
    60     return 0;
    61 }
    62 
    63 intptr_t PrintNum(void *blah, intptr_t *params)
    64 {
    65     fprintf(stdout, "%i", *reinterpret_cast<int *>(&params[1]));
    66     return 0;
    67 }
    68 
    69 intptr_t PrintString(void *blah, intptr_t *params)
    70 {
    71     fprintf(stdout, "%s", *reinterpret_cast<const char **>(&params[1]));
    72     return 0;
    73 }
    74 
    75 int main(int argc, char **argv)
    76 {
    77     if (argc < 2) {
    78         fprintf(stderr, "Usage: <file>\n");
    79         return 1;
    80     }
    81 
    82     if (!Keima::Initialize())
    83         return 1;
    84 
    85     int rval = 0;
    86 
    87     Keima::InstallMessageReporter(&s_Reporter);
    88     {
    89         HandleScope scope;
    90         Local<Module> module = Compile(argv[1]);
    91         if (!module)
    92             return 1;
    93 
    94         Keima::CollectGarbage();
    95 
    96         // Look for a public named "main".
    97         Local<Function> fun;
    98         for (unsigned i = 0; i < module->numPublics(); i++) {
    99             if (strcmp(module->getPublic(i)->name()->chars(), "main") == 0) {
   100                 fun = module->getPublic(i);
   101                 break;
   102             }
   103         }
   104 
   105         for (unsigned i = 0; i < module->numNatives(); i++) {
   106             Local<Native> native = module->getNative(i);
   107 
   108             if (strcmp(native->name()->chars(), "PrintFloat") == 0)
   109                 native->bind(reinterpret_cast<void *>(PrintFloat));
   110             else if (strcmp(native->name()->chars(), "PrintNum") == 0)
   111                 native->bind(reinterpret_cast<void *>(PrintNum));
   112             else if (strcmp(native->name()->chars(), "PrintString") == 0)
   113                 native->bind(reinterpret_cast<void *>(PrintString));
   114         }
   115 
   116 
   117         if (!fun) {
   118             fprintf(stdout, "Plugin compiles!\nNot running; no public 'main'.\n");
   119         } else {
   120             Local<Function> fun = module->getPublic(0);
   121             if (!Keima::Invoke(fun, NULL, 0, true, &rval))
   122                 rval = 1;
   123         }
   124     }
   125 
   126     Keima::Shutdown();
   127 
   128     return rval;
   129 }
   130 
   131 /* Overload a few things to prevent libstdc++ linking */
   132 #if defined __linux__ || defined __APPLE__
   133 extern "C" void __cxa_pure_virtual(void)
   134 {
   135 }
   136 
   137 void *operator new(size_t size)
   138 {
   139     return malloc(size);
   140 }
   141 
   142 void *operator new[](size_t size) 
   143 {
   144     return malloc(size);
   145 }
   146 
   147 void operator delete(void *ptr) 
   148 {
   149     free(ptr);
   150 }
   151 
   152 void operator delete[](void * ptr)
   153 {
   154     free(ptr);
   155 }
   156 #endif
   157