views:

116

answers:

2

I am trying to create an objective c interface that encapsulates the functionality of storing and running a lua script (compiled or not.) My code for the script interface is as follows:

#import <Cocoa/Cocoa.h>
#import "Types.h"
#import "lua.h"
#include "lualib.h"
#include "lauxlib.h"

@interface Script : NSObject<NSCoding> {
@public
  s32 size;
  s8* data;
  BOOL done;
}

@property s32 size;
@property s8* data;
@property BOOL done;

- (id) initWithScript: (u8*)data andSize:(s32)size;
- (id) initFromFile: (const char*)file;
- (void) runWithState: (lua_State*)state;
- (void) encodeWithCoder: (NSCoder*)coder;
- (id) initWithCoder: (NSCoder*)coder;

@end

#import "Script.h"

@implementation Script

@synthesize size;
@synthesize data;
@synthesize done;

- (id) initWithScript: (s8*)d andSize:(s32)s
{
        self = [super init];
 self->size = s;
 self->data = d;
 return self;
}

- (id) initFromFile:(const char *)file
{
        FILE* p;
     p = fopen(file, "rb");
     if(p == NULL) return [super init];
      fseek(p, 0, SEEK_END);
        s32 fs = ftell(p);
     rewind(p);
     u8* buffer = (u8*)malloc(fs);
     fread(buffer, 1, fs, p);
      fclose(p);

     return [self initWithScript:buffer andSize:size];
}

 - (void) runWithState: (lua_State*)state
 {
  if(luaL_loadbuffer(state, [self data], [self size], "Script") != 0)
  {
   NSLog(@"Error loading lua chunk.");
   return;
  }
  lua_pcall(state, 0, LUA_MULTRET, 0);

}

- (void) encodeWithCoder: (NSCoder*)coder
{
  [coder encodeInt: size forKey: @"Script.size"];
 [coder encodeBytes:data length:size forKey:@"Script.data"];
}

- (id) initWithCoder: (NSCoder*)coder
{
 self = [super init];
 NSUInteger actualSize;
 size = [coder decodeIntForKey: @"Script.size"];
 data = [[coder decodeBytesForKey:@"Script.data" returnedLength:&actualSize] retain];
 return self;
}

@end

Here is the main method: #import "Script.h"

int main(int argc, char* argv[])
{
 Script* script = [[Script alloc] initFromFile:"./test.lua"];
 lua_State* state = luaL_newstate();
 luaL_openlibs(state);
 luaL_dostring(state, "print(_VERSION)");
 [script runWithState:state];
 luaL_dostring(state, "print(_VERSION)");
 lua_close(state);
}

And the lua script is just: print("O Hai World!")

Loading the file is correct, but I think it messes up at pcall.

Any Help is greatly appreciated.

Heading

+2  A: 

Your code is so complex that there are no obvious faults. However, your next step should be to check the return value from lua_pcall. If it is nonzero, there will be an error message on the top of the stack which you can print via

fprintf(stderr, "Pcall failed: %s\n", lua_tostring(state, -1));

If you don't get a useful error message, my next step would be to dump the Lua stack. How many elements are on it? What is the (Lua) type of each element? What is the value. Functions lua_top, and luaL_typename will be useful. To print the value you will have to switch on the results of lua_type. Good luck.

Norman Ramsey
Okay, it's saying Pcall failed: (Null). Where should I go from here?
beta
@beta: quite baffling. My next step would be to dump the Lua stack. How many elements are on it? What is the (Lua) type of each element? What is the value. Functions `lua_top`, and `luaL_typename` will be useful. To print the value you will have to switch on the results of `lua_type`. Good luck.
Norman Ramsey
A: 

I didn't run your code. But at first glance, I found that the signature of initWithScript: are different between header file (using u8*) and source file (using s8*).

torus