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