src/main.cpp
author David Anderson <dvander@alliedmods.net>
Sat Sep 15 17:39:45 2012 -0700 (2012-09-15)
changeset 184 387d76b1e981
parent 174 e718b56aba78
child 195 c1ba166f3fc4
permissions -rw-r--r--
Add support for array reference semantics.
     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() && index < 10) {
    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             if (!Keima::Invoke(fun, NULL, 0, true, &rval))
   121                 rval = 1;
   122         }
   123     }
   124 
   125     Keima::Shutdown();
   126 
   127     return rval;
   128 }
   129 
   130 /* Overload a few things to prevent libstdc++ linking */
   131 #if defined __linux__ || defined __APPLE__
   132 extern "C" void __cxa_pure_virtual(void)
   133 {
   134 }
   135 
   136 void *operator new(size_t size)
   137 {
   138     return malloc(size);
   139 }
   140 
   141 void *operator new[](size_t size) 
   142 {
   143     return malloc(size);
   144 }
   145 
   146 void operator delete(void *ptr) 
   147 {
   148     free(ptr);
   149 }
   150 
   151 void operator delete[](void * ptr)
   152 {
   153     free(ptr);
   154 }
   155 #endif
   156