issue #181 remove old c tests
parent
ea5e34f447
commit
0796d0da0b
@ -1,7 +0,0 @@
|
||||
The tests in this folder are run via the CMake CTest capability.
|
||||
|
||||
On UNIX systems, just execute::
|
||||
|
||||
make test
|
||||
|
||||
On Windows, when using Visual Studio 2013, you can run a build on RUN_TESTS project.
|
@ -1,40 +0,0 @@
|
||||
#include <ctype.h>
|
||||
#include <limits.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "lua.h"
|
||||
#include "lauxlib.h"
|
||||
#include "lualib.h"
|
||||
#include "ravi_ast.h"
|
||||
|
||||
static int test_buildast(const char *code)
|
||||
{
|
||||
int rc = 0;
|
||||
lua_State *L;
|
||||
L = luaL_newstate();
|
||||
if (raviL_build_ast_from_buffer(L, code, strlen(code), "testcode", NULL) != 0) {
|
||||
rc = 1;
|
||||
fprintf(stderr, "%s\n", lua_tostring(L, -1));
|
||||
lua_pop(L, 1); /* pop error message from the stack */
|
||||
}
|
||||
else
|
||||
raviL_dumpast(L);
|
||||
lua_close(L);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int failures = 0;
|
||||
//
|
||||
failures += test_buildast("return");
|
||||
failures += test_buildast("return 1");
|
||||
failures += test_buildast("return 1+2");
|
||||
|
||||
return failures ? 1 : 0;
|
||||
}
|
@ -1,264 +0,0 @@
|
||||
#include "ravi_llvm.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
// This file contains a basic test case that covers following:
|
||||
// Creating a function that takes pointer to struct as argument
|
||||
// The function gets value from one of the fields in the struct
|
||||
// And returns it
|
||||
// The equivalent C program is:
|
||||
//
|
||||
// extern int printf(const char *, ...);
|
||||
//
|
||||
// struct GCObject {
|
||||
// struct GCObject *next;
|
||||
// unsigned char a;
|
||||
// unsigned char b;
|
||||
// };
|
||||
//
|
||||
// int testfunc(struct GCObject *obj) {
|
||||
// printf("value = %d\n", obj->a);
|
||||
// return obj->a;
|
||||
// }
|
||||
|
||||
// This mirrors the Lua GCObject structure in lobject.h
|
||||
typedef struct RaviGCObject {
|
||||
struct RaviGCObject *next;
|
||||
unsigned char b1;
|
||||
unsigned char b2;
|
||||
} RaviGCObject;
|
||||
|
||||
// Our prototype for the JITted function
|
||||
typedef int (*myfunc_t)(RaviGCObject *);
|
||||
|
||||
int test1() {
|
||||
// FIXME context should be deleted at the end but here we
|
||||
// don't bother
|
||||
llvm::LLVMContext *context = new llvm::LLVMContext();
|
||||
|
||||
// Module is the translation unit
|
||||
std::unique_ptr<llvm::Module> theModule =
|
||||
std::unique_ptr<llvm::Module>(new llvm::Module("ravi", *context));
|
||||
llvm::Module *module = theModule.get();
|
||||
llvm::IRBuilder<> builder(*context);
|
||||
|
||||
#if defined(_WIN32) && (!defined(_WIN64) || LLVM_VERSION_MINOR < 7)
|
||||
// On Windows we get error saying incompatible object format
|
||||
// Reading posts on mailining lists I found that the issue is that COEFF
|
||||
// format is not supported and therefore we need to set -elf as the object
|
||||
// format
|
||||
auto triple = llvm::sys::getProcessTriple();
|
||||
// module->setTargetTriple("x86_64-pc-win32-elf");
|
||||
module->setTargetTriple(triple + "-elf");
|
||||
#endif
|
||||
|
||||
// create a GCObject structure as defined in lobject.h
|
||||
llvm::StructType *structType =
|
||||
llvm::StructType::create(*context, "RaviGCObject");
|
||||
llvm::PointerType *pstructType =
|
||||
llvm::PointerType::get(structType, 0); // pointer to RaviGCObject
|
||||
std::vector<llvm::Type *> elements;
|
||||
elements.push_back(pstructType);
|
||||
elements.push_back(llvm::Type::getInt8Ty(*context));
|
||||
elements.push_back(llvm::Type::getInt8Ty(*context));
|
||||
structType->setBody(elements);
|
||||
#if defined(LLVM_ENABLE_DUMP)
|
||||
structType->dump();
|
||||
#endif
|
||||
// Create printf declaration
|
||||
std::vector<llvm::Type *> args;
|
||||
args.push_back(llvm::Type::getInt8PtrTy(*context));
|
||||
// accepts a char*, is vararg, and returns int
|
||||
llvm::FunctionType *printfType =
|
||||
llvm::FunctionType::get(builder.getInt32Ty(), args, true);
|
||||
llvm::Constant *printfFunc =
|
||||
module->getOrInsertFunction("printf", printfType);
|
||||
|
||||
// Create the testfunc()
|
||||
args.clear();
|
||||
args.push_back(pstructType);
|
||||
llvm::FunctionType *funcType =
|
||||
llvm::FunctionType::get(builder.getInt32Ty(), args, false);
|
||||
llvm::Function *mainFunc = llvm::Function::Create(
|
||||
funcType, llvm::Function::ExternalLinkage, "testfunc", module);
|
||||
llvm::BasicBlock *entry =
|
||||
llvm::BasicBlock::Create(*context, "entrypoint", mainFunc);
|
||||
builder.SetInsertPoint(entry);
|
||||
|
||||
// printf format string
|
||||
llvm::Value *formatStr = builder.CreateGlobalStringPtr("value = %d\n");
|
||||
|
||||
// Get the first argument which is RaviGCObject *
|
||||
auto argiter = mainFunc->arg_begin();
|
||||
llvm::Value *arg1 = &(*argiter);
|
||||
arg1->setName("obj");
|
||||
|
||||
// Now we need a GEP for the second field in RaviGCObject
|
||||
std::vector<llvm::Value *> values;
|
||||
llvm::APInt zero(32, 0);
|
||||
llvm::APInt one(32, 1);
|
||||
// This is the array offset into RaviGCObject*
|
||||
values.push_back(
|
||||
llvm::Constant::getIntegerValue(llvm::Type::getInt32Ty(*context), zero));
|
||||
// This is the field offset
|
||||
values.push_back(
|
||||
llvm::Constant::getIntegerValue(llvm::Type::getInt32Ty(*context), one));
|
||||
|
||||
// Create the GEP value
|
||||
llvm::Value *arg1_a = builder.CreateGEP(arg1, values, "ptr");
|
||||
|
||||
// Now retrieve the data from the pointer address
|
||||
llvm::Value *tmp1 = builder.CreateLoad(arg1_a, "a");
|
||||
// As the retrieved value is a byte - convert to int i
|
||||
llvm::Value *tmp2 =
|
||||
builder.CreateZExt(tmp1, llvm::Type::getInt32Ty(*context), "i");
|
||||
|
||||
// Call the printf function
|
||||
values.clear();
|
||||
values.push_back(formatStr);
|
||||
values.push_back(tmp2);
|
||||
builder.CreateCall(printfFunc, values);
|
||||
|
||||
// return i
|
||||
builder.CreateRet(tmp2);
|
||||
#if defined(LLVM_ENABLE_DUMP)
|
||||
module->dump();
|
||||
#endif
|
||||
|
||||
// Lets create the MCJIT engine
|
||||
std::string errStr;
|
||||
#if LLVM_VERSION_MAJOR > 3 || LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR > 5
|
||||
std::unique_ptr<llvm::Module> module_(module);
|
||||
auto engine = llvm::EngineBuilder(std::move(module_))
|
||||
.setErrorStr(&errStr)
|
||||
.setEngineKind(llvm::EngineKind::JIT)
|
||||
.create();
|
||||
#else
|
||||
auto engine = llvm::EngineBuilder(module)
|
||||
.setErrorStr(&errStr)
|
||||
.setEngineKind(llvm::EngineKind::JIT)
|
||||
.setUseMCJIT(true)
|
||||
.create();
|
||||
#endif
|
||||
if (!engine) {
|
||||
std::cerr << "Failed to construct MCJIT ExecutionEngine: " << errStr
|
||||
<< "\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Now lets compile our function into machine code
|
||||
std::string funcname = "testfunc";
|
||||
myfunc_t funcptr = (myfunc_t)engine->getFunctionAddress(funcname);
|
||||
if (funcptr == nullptr) {
|
||||
std::cerr << "Failed to obtain compiled function\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Run the function and test results.
|
||||
RaviGCObject obj = {NULL, 42, 65};
|
||||
int ans = funcptr(&obj);
|
||||
printf("The answer is %d\n", ans);
|
||||
return ans == 42 ? 0 : 1;
|
||||
}
|
||||
|
||||
extern "C" int mytest(RaviGCObject *obj) {
|
||||
printf("value = %d\n", obj->b1);
|
||||
return obj->b1;
|
||||
}
|
||||
|
||||
#if 0
|
||||
// This version of the test calls mytest() rather than
|
||||
// printf() as in test1(). Also we use RaviJITState and related
|
||||
// infrastructure
|
||||
int test2() {
|
||||
|
||||
auto jitStatePtr = ravi::RaviJITStateFactory::newJITState();
|
||||
ravi::RaviJITState &jitState = *jitStatePtr.get();
|
||||
|
||||
jitState.dump();
|
||||
|
||||
llvm::LLVMContext &context = jitState.context();
|
||||
llvm::IRBuilder<> builder(context);
|
||||
|
||||
// create a GCObject structure as defined in lobject.h
|
||||
llvm::StructType *structType =
|
||||
llvm::StructType::create(context, "RaviGCObject");
|
||||
llvm::PointerType *pstructType =
|
||||
llvm::PointerType::get(structType, 0); // pointer to RaviGCObject
|
||||
std::vector<llvm::Type *> elements;
|
||||
elements.push_back(pstructType);
|
||||
elements.push_back(llvm::Type::getInt8Ty(context));
|
||||
elements.push_back(llvm::Type::getInt8Ty(context));
|
||||
structType->setBody(elements);
|
||||
#if defined(LLVM_ENABLE_DUMP)
|
||||
structType->dump();
|
||||
#endif
|
||||
|
||||
// Create declaration for mytest
|
||||
// int mytest(RaviGCObject *obj)
|
||||
std::vector<llvm::Type *> args;
|
||||
args.push_back(pstructType);
|
||||
llvm::FunctionType *mytestFuncType =
|
||||
llvm::FunctionType::get(builder.getInt32Ty(), args, false);
|
||||
|
||||
// Create the testfunc()
|
||||
args.clear();
|
||||
args.push_back(pstructType);
|
||||
llvm::FunctionType *funcType =
|
||||
llvm::FunctionType::get(builder.getInt32Ty(), args, false);
|
||||
ravi::RaviJITFunction *func = jitState.createFunction(
|
||||
funcType, llvm::Function::ExternalLinkage, "testfunc");
|
||||
|
||||
llvm::Function *mainFunc = func->function();
|
||||
llvm::BasicBlock *entry =
|
||||
llvm::BasicBlock::Create(context, "entrypoint", mainFunc);
|
||||
builder.SetInsertPoint(entry);
|
||||
|
||||
// Get the first argument which is RaviGCObject *
|
||||
auto argiter = mainFunc->arg_begin();
|
||||
llvm::Value *arg1 = argiter++;
|
||||
arg1->setName("obj");
|
||||
|
||||
// Add an extern int mytest(RaviGCObject *obj) and link this
|
||||
// to mytest()
|
||||
llvm::Constant *mytestFunc =
|
||||
func->addExternFunction(mytestFuncType, reinterpret_cast<void *>(&mytest), "mytest");
|
||||
|
||||
// Call the mytest() function
|
||||
std::vector<llvm::Value *> values;
|
||||
values.push_back(arg1);
|
||||
llvm::Value *tmp2 = builder.CreateCall(mytestFunc, values, "i");
|
||||
|
||||
// return i
|
||||
builder.CreateRet(tmp2);
|
||||
func->dump();
|
||||
|
||||
// Now lets compile our function into machine code
|
||||
myfunc_t funcptr = (myfunc_t)func->compile();
|
||||
if (funcptr == nullptr) {
|
||||
std::cerr << "Failed to obtain compiled function\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Run the function and test results.
|
||||
RaviGCObject obj = {NULL, 42, 65};
|
||||
int ans = funcptr(&obj);
|
||||
printf("The answer is %d\n", ans);
|
||||
return ans == 42 ? 0 : 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
int main() {
|
||||
|
||||
// Looks like unless following three lines are not executed then
|
||||
// ExecutionEngine cannot be created
|
||||
llvm::InitializeNativeTarget();
|
||||
llvm::InitializeNativeTargetAsmPrinter();
|
||||
llvm::InitializeNativeTargetAsmParser();
|
||||
|
||||
int failure_count = 0;
|
||||
failure_count += test1();
|
||||
// failure_count += test2();
|
||||
|
||||
return failure_count != 0 ? 1 : 0;
|
||||
}
|
@ -1,531 +0,0 @@
|
||||
#include <ctype.h>
|
||||
#include <limits.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <inttypes.h>
|
||||
#include <assert.h>
|
||||
|
||||
#define check_exp(c,e) (assert(c), (e))
|
||||
|
||||
/*
|
||||
** basic types
|
||||
*/
|
||||
#define LUA_TNONE (-1)
|
||||
|
||||
#define LUA_TNIL 0
|
||||
#define LUA_TBOOLEAN 1
|
||||
#define LUA_TLIGHTUSERDATA 2
|
||||
#define LUA_TNUMBER 3
|
||||
#define LUA_TSTRING 4
|
||||
#define LUA_TTABLE 5
|
||||
#define LUA_TFUNCTION 6
|
||||
#define LUA_TUSERDATA 7
|
||||
#define LUA_TTHREAD 8
|
||||
|
||||
#define LUA_NUMTAGS 9
|
||||
|
||||
/*
|
||||
** Extra tags for non-values
|
||||
*/
|
||||
#define LUA_TPROTO LUA_NUMTAGS
|
||||
#define LUA_TDEADKEY (LUA_NUMTAGS+1)
|
||||
|
||||
/*
|
||||
** number of all possible tags (including LUA_TNONE but excluding DEADKEY)
|
||||
*/
|
||||
#define LUA_TOTALTAGS (LUA_TPROTO + 2)
|
||||
|
||||
|
||||
/*
|
||||
** tags for Tagged Values have the following use of bits:
|
||||
** bits 0-3: actual tag (a LUA_T* value)
|
||||
** bits 4-5: variant bits
|
||||
** bit 6: whether value is collectable
|
||||
*/
|
||||
|
||||
#define VARBITS (3 << 4)
|
||||
|
||||
|
||||
/*
|
||||
** LUA_TFUNCTION variants:
|
||||
** 0 - Lua function
|
||||
** 1 - light C function
|
||||
** 2 - regular C function (closure)
|
||||
*/
|
||||
|
||||
/* Variant tags for functions */
|
||||
#define LUA_TLCL (LUA_TFUNCTION | (0 << 4)) /* Lua closure */
|
||||
#define LUA_TLCF (LUA_TFUNCTION | (1 << 4)) /* light C function */
|
||||
#define LUA_TCCL (LUA_TFUNCTION | (2 << 4)) /* C closure */
|
||||
|
||||
|
||||
/* Variant tags for strings */
|
||||
#define LUA_TSHRSTR (LUA_TSTRING | (0 << 4)) /* short strings */
|
||||
#define LUA_TLNGSTR (LUA_TSTRING | (1 << 4)) /* long strings */
|
||||
|
||||
|
||||
/* Variant tags for numbers */
|
||||
#define LUA_TNUMFLT (LUA_TNUMBER | (0 << 4)) /* float numbers */
|
||||
#define LUA_TNUMINT (LUA_TNUMBER | (1 << 4)) /* integer numbers */
|
||||
|
||||
|
||||
/* Bit mark for collectable types */
|
||||
#define BIT_ISCOLLECTABLE (1 << 7)
|
||||
|
||||
/* mark a tag as collectable */
|
||||
#define ctb(t) ((t) | BIT_ISCOLLECTABLE)
|
||||
|
||||
|
||||
typedef struct lua_State lua_State;
|
||||
typedef long long lua_Integer;
|
||||
typedef double lua_Number;
|
||||
typedef int (*lua_CFunction)(lua_State *);
|
||||
typedef unsigned char lu_byte;
|
||||
|
||||
/*
|
||||
** Common type for all collectable objects
|
||||
*/
|
||||
typedef struct GCObject GCObject;
|
||||
|
||||
|
||||
/*
|
||||
** Common Header for all collectable objects (in macro form, to be
|
||||
** included in other objects)
|
||||
*/
|
||||
#define CommonHeader GCObject *next; lu_byte tt; lu_byte marked
|
||||
|
||||
|
||||
/*
|
||||
** Common type has only the common header
|
||||
*/
|
||||
struct GCObject {
|
||||
CommonHeader;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*
|
||||
** Union of all Lua values
|
||||
*/
|
||||
typedef union Value Value;
|
||||
|
||||
#define RAVI_NAN_TAGGING 1
|
||||
#if RAVI_NAN_TAGGING
|
||||
|
||||
#define RAVI_NAN_TAG 0x7ffc0000
|
||||
#define RAVI_TYPE_MASK 0x0000ffff
|
||||
|
||||
/*
|
||||
TODO This is little endian - need to switch lo/hi for big
|
||||
endian
|
||||
*/
|
||||
typedef struct ravi_HiLo {
|
||||
int lo;
|
||||
int hi;
|
||||
} HiLo;
|
||||
|
||||
typedef union ravi_TypeOrDouble {
|
||||
HiLo hilo;
|
||||
double n;
|
||||
/* for debugging */
|
||||
unsigned char bytes[8];
|
||||
} TypeOrDouble;
|
||||
|
||||
/*
|
||||
** Tagged Values. This is the basic representation of values in Lua,
|
||||
** an actual value plus a tag with its type.
|
||||
*/
|
||||
|
||||
#define TValuefields Value value_; TypeOrDouble tt_
|
||||
|
||||
typedef struct lua_TValue TValue;
|
||||
|
||||
|
||||
/* macro defining a nil value */
|
||||
#define NILCONSTANT {NULL}, { {0, (RAVI_NAN_TAG|LUA_TNIL)} }
|
||||
|
||||
/* Note that numbers are not stored in value_ when NaN tagging is ON */
|
||||
#define val_(o) ((o)->value_)
|
||||
#define numval_(o) ((o)->tt_)
|
||||
|
||||
#define extracttype(o) ((o)->tt_.hilo.hi & RAVI_NAN_TAG)
|
||||
|
||||
/* raw type tag of a TValue */
|
||||
#define rttype(o) (extracttype(o)==RAVI_NAN_TAG ? ((o)->tt_.hilo.hi & RAVI_TYPE_MASK) : LUA_TNUMFLT)
|
||||
|
||||
/* tag with no variants (bits 0-3) */
|
||||
#define novariant(x) ((x) & 0x0F)
|
||||
|
||||
/* type tag of a TValue (bits 0-3 for tags + variant bits 4-5) */
|
||||
#define ttype(o) (rttype(o) & 0x3F)
|
||||
|
||||
/* type tag of a TValue with no variants (bits 0-3) */
|
||||
#define ttnov(o) (novariant(rttype(o)))
|
||||
|
||||
|
||||
/* Macros to test type */
|
||||
#define checktag(o,t) (rttype(o) == (t))
|
||||
#define checktype(o,t) (ttnov(o) == (t))
|
||||
#define ttisfloat(o) (extracttype(o) != RAVI_NAN_TAG)
|
||||
#define ttisinteger(o) checktag((o), LUA_TNUMINT)
|
||||
#define ttisnumber(o) (ttisfloat(o) || ttisinteger(o))
|
||||
#define ttisnil(o) checktag((o), LUA_TNIL)
|
||||
#define ttisboolean(o) checktag((o), LUA_TBOOLEAN)
|
||||
#define ttislightuserdata(o) checktag((o), LUA_TLIGHTUSERDATA)
|
||||
#define ttisstring(o) checktype((o), LUA_TSTRING)
|
||||
#define ttisshrstring(o) checktag((o), ctb(LUA_TSHRSTR))
|
||||
#define ttislngstring(o) checktag((o), ctb(LUA_TLNGSTR))
|
||||
#define ttistable(o) checktag((o), ctb(LUA_TTABLE))
|
||||
#define ttisfunction(o) checktype(o, LUA_TFUNCTION)
|
||||
#define ttisclosure(o) ((rttype(o) & 0x1F) == LUA_TFUNCTION)
|
||||
#define ttisCclosure(o) checktag((o), ctb(LUA_TCCL))
|
||||
#define ttisLclosure(o) checktag((o), ctb(LUA_TLCL))
|
||||
#define ttislcf(o) checktag((o), LUA_TLCF)
|
||||
#define ttisfulluserdata(o) checktag((o), ctb(LUA_TUSERDATA))
|
||||
#define ttisthread(o) checktag((o), ctb(LUA_TTHREAD))
|
||||
#define ttisdeadkey(o) checktag((o), LUA_TDEADKEY)
|
||||
|
||||
|
||||
/* Macros to access values */
|
||||
#define ivalue(o) check_exp(ttisinteger(o), val_(o).i)
|
||||
#define fltvalue(o) check_exp(ttisfloat(o), numval_(o).n)
|
||||
#define nvalue(o) check_exp(ttisnumber(o), \
|
||||
(ttisinteger(o) ? cast_num(ivalue(o)) : fltvalue(o)))
|
||||
#define gcvalue(o) check_exp(iscollectable(o), val_(o).gc)
|
||||
#define pvalue(o) check_exp(ttislightuserdata(o), val_(o).p)
|
||||
#define tsvalue(o) check_exp(ttisstring(o), gco2ts(val_(o).gc))
|
||||
#define uvalue(o) check_exp(ttisfulluserdata(o), gco2u(val_(o).gc))
|
||||
#define clvalue(o) check_exp(ttisclosure(o), gco2cl(val_(o).gc))
|
||||
#define clLvalue(o) check_exp(ttisLclosure(o), gco2lcl(val_(o).gc))
|
||||
#define clCvalue(o) check_exp(ttisCclosure(o), gco2ccl(val_(o).gc))
|
||||
#define fvalue(o) check_exp(ttislcf(o), val_(o).f)
|
||||
#define hvalue(o) check_exp(ttistable(o), gco2t(val_(o).gc))
|
||||
#define bvalue(o) check_exp(ttisboolean(o), val_(o).b)
|
||||
#define thvalue(o) check_exp(ttisthread(o), gco2th(val_(o).gc))
|
||||
/* a dead value may get the 'gc' field, but cannot access its contents */
|
||||
#define deadvalue(o) check_exp(ttisdeadkey(o), cast(void *, val_(o).gc))
|
||||
|
||||
#define l_isfalse(o) (ttisnil(o) || (ttisboolean(o) && bvalue(o) == 0))
|
||||
|
||||
|
||||
#define iscollectable(o) (rttype(o) & BIT_ISCOLLECTABLE)
|
||||
|
||||
|
||||
/* Macros for internal tests */
|
||||
#define righttt(obj) (ttype(obj) == gcvalue(obj)->tt)
|
||||
|
||||
#define checkliveness(g,obj) \
|
||||
lua_longassert(!iscollectable(obj) || \
|
||||
(righttt(obj) && !isdead(g,gcvalue(obj))))
|
||||
|
||||
|
||||
/* Macros to set values */
|
||||
#define settt_(o,t) ((o)->tt_.hilo.hi=(t|RAVI_NAN_TAG))
|
||||
|
||||
#define setfltvalue(obj,x) \
|
||||
{ TValue *io=(obj); numval_(io).n=(x); }
|
||||
|
||||
#define setivalue(obj,x) \
|
||||
{ TValue *io=(obj); val_(io).i=(x); settt_(io, LUA_TNUMINT); }
|
||||
|
||||
#define setnilvalue(obj) settt_(obj, LUA_TNIL)
|
||||
|
||||
#define setfvalue(obj,x) \
|
||||
{ TValue *io=(obj); val_(io).f=(x); settt_(io, LUA_TLCF); }
|
||||
|
||||
#define setpvalue(obj,x) \
|
||||
{ TValue *io=(obj); val_(io).p=(x); settt_(io, LUA_TLIGHTUSERDATA); }
|
||||
|
||||
#define setbvalue(obj,x) \
|
||||
{ TValue *io=(obj); val_(io).b=(x); settt_(io, LUA_TBOOLEAN); }
|
||||
|
||||
#define setgcovalue(L,obj,x) \
|
||||
{ TValue *io = (obj); GCObject *i_g=(x); \
|
||||
val_(io).gc = i_g; settt_(io, ctb(i_g->tt)); }
|
||||
|
||||
#define setsvalue(L,obj,x) \
|
||||
{ TValue *io = (obj); TString *x_ = (x); \
|
||||
val_(io).gc = obj2gco(x_); settt_(io, ctb(x_->tt)); \
|
||||
checkliveness(G(L),io); }
|
||||
|
||||
#define setuvalue(L,obj,x) \
|
||||
{ TValue *io = (obj); Udata *x_ = (x); \
|
||||
val_(io).gc = obj2gco(x_); settt_(io, ctb(LUA_TUSERDATA)); \
|
||||
checkliveness(G(L),io); }
|
||||
|
||||
#define setthvalue(L,obj,x) \
|
||||
{ TValue *io = (obj); lua_State *x_ = (x); \
|
||||
val_(io).gc = obj2gco(x_); settt_(io, ctb(LUA_TTHREAD)); \
|
||||
checkliveness(G(L),io); }
|
||||
|
||||
#define setclLvalue(L,obj,x) \
|
||||
{ TValue *io = (obj); LClosure *x_ = (x); \
|
||||
val_(io).gc = obj2gco(x_); settt_(io, ctb(LUA_TLCL)); \
|
||||
checkliveness(G(L),io); }
|
||||
|
||||
#define setclCvalue(L,obj,x) \
|
||||
{ TValue *io = (obj); CClosure *x_ = (x); \
|
||||
val_(io).gc = obj2gco(x_); settt_(io, ctb(LUA_TCCL)); \
|
||||
checkliveness(G(L),io); }
|
||||
|
||||
#define sethvalue(L,obj,x) \
|
||||
{ TValue *io = (obj); Table *x_ = (x); \
|
||||
val_(io).gc = obj2gco(x_); settt_(io, ctb(LUA_TTABLE)); \
|
||||
checkliveness(G(L),io); }
|
||||
|
||||
#define setdeadvalue(obj) settt_(obj, LUA_TDEADKEY)
|
||||
|
||||
|
||||
|
||||
#define setobj(L,obj1,obj2) \
|
||||
{ TValue *io1=(obj1); *io1 = *(obj2); \
|
||||
(void)L; checkliveness(G(L),io1); }
|
||||
|
||||
|
||||
/*
|
||||
** different types of assignments, according to destination
|
||||
*/
|
||||
|
||||
/* from stack to (same) stack */
|
||||
#define setobjs2s setobj
|
||||
/* to stack (not from same stack) */
|
||||
#define setobj2s setobj
|
||||
#define setsvalue2s setsvalue
|
||||
#define sethvalue2s sethvalue
|
||||
#define setptvalue2s setptvalue
|
||||
/* from table to same table */
|
||||
#define setobjt2t setobj
|
||||
/* to table */
|
||||
#define setobj2t setobj
|
||||
/* to new object */
|
||||
#define setobj2n setobj
|
||||
#define setsvalue2n setsvalue
|
||||
|
||||
#else
|
||||
/*
|
||||
** Tagged Values. This is the basic representation of values in Lua,
|
||||
** an actual value plus a tag with its type.
|
||||
*/
|
||||
|
||||
#define TValuefields Value value_; int tt_
|
||||
|
||||
typedef struct lua_TValue TValue;
|
||||
|
||||
|
||||
/* macro defining a nil value */
|
||||
#define NILCONSTANT {NULL}, LUA_TNIL
|
||||
|
||||
|
||||
#define val_(o) ((o)->value_)
|
||||
|
||||
|
||||
/* raw type tag of a TValue */
|
||||
#define rttype(o) ((o)->tt_)
|
||||
|
||||
/* tag with no variants (bits 0-3) */
|
||||
#define novariant(x) ((x) & 0x0F)
|
||||
|
||||
/* type tag of a TValue (bits 0-3 for tags + variant bits 4-5) */
|
||||
#define ttype(o) (rttype(o) & 0x3F)
|
||||
|
||||
/* type tag of a TValue with no variants (bits 0-3) */
|
||||
#define ttnov(o) (novariant(rttype(o)))
|
||||
|
||||
|
||||
/* Macros to test type */
|
||||
#define checktag(o,t) (rttype(o) == (t))
|
||||
#define checktype(o,t) (ttnov(o) == (t))
|
||||
#define ttisnumber(o) checktype((o), LUA_TNUMBER)
|
||||
#define ttisfloat(o) checktag((o), LUA_TNUMFLT)
|
||||
#define ttisinteger(o) checktag((o), LUA_TNUMINT)
|
||||
#define ttisnil(o) checktag((o), LUA_TNIL)
|
||||
#define ttisboolean(o) checktag((o), LUA_TBOOLEAN)
|
||||
#define ttislightuserdata(o) checktag((o), LUA_TLIGHTUSERDATA)
|
||||
#define ttisstring(o) checktype((o), LUA_TSTRING)
|
||||
#define ttisshrstring(o) checktag((o), ctb(LUA_TSHRSTR))
|
||||
#define ttislngstring(o) checktag((o), ctb(LUA_TLNGSTR))
|
||||
#define ttistable(o) checktag((o), ctb(LUA_TTABLE))
|
||||
#define ttisfunction(o) checktype(o, LUA_TFUNCTION)
|
||||
#define ttisclosure(o) ((rttype(o) & 0x1F) == LUA_TFUNCTION)
|
||||
#define ttisCclosure(o) checktag((o), ctb(LUA_TCCL))
|
||||
#define ttisLclosure(o) checktag((o), ctb(LUA_TLCL))
|
||||
#define ttislcf(o) checktag((o), LUA_TLCF)
|
||||
#define ttisfulluserdata(o) checktag((o), ctb(LUA_TUSERDATA))
|
||||
#define ttisthread(o) checktag((o), ctb(LUA_TTHREAD))
|
||||
#define ttisdeadkey(o) checktag((o), LUA_TDEADKEY)
|
||||
|
||||
|
||||
/* Macros to access values */
|
||||
#define ivalue(o) check_exp(ttisinteger(o), val_(o).i)
|
||||
#define fltvalue(o) check_exp(ttisfloat(o), val_(o).n)
|
||||
#define nvalue(o) check_exp(ttisnumber(o), \
|
||||
(ttisinteger(o) ? cast_num(ivalue(o)) : fltvalue(o)))
|
||||
#define gcvalue(o) check_exp(iscollectable(o), val_(o).gc)
|
||||
#define pvalue(o) check_exp(ttislightuserdata(o), val_(o).p)
|
||||
#define tsvalue(o) check_exp(ttisstring(o), gco2ts(val_(o).gc))
|
||||
#define uvalue(o) check_exp(ttisfulluserdata(o), gco2u(val_(o).gc))
|
||||
#define clvalue(o) check_exp(ttisclosure(o), gco2cl(val_(o).gc))
|
||||
#define clLvalue(o) check_exp(ttisLclosure(o), gco2lcl(val_(o).gc))
|
||||
#define clCvalue(o) check_exp(ttisCclosure(o), gco2ccl(val_(o).gc))
|
||||
#define fvalue(o) check_exp(ttislcf(o), val_(o).f)
|
||||
#define hvalue(o) check_exp(ttistable(o), gco2t(val_(o).gc))
|
||||
#define bvalue(o) check_exp(ttisboolean(o), val_(o).b)
|
||||
#define thvalue(o) check_exp(ttisthread(o), gco2th(val_(o).gc))
|
||||
/* a dead value may get the 'gc' field, but cannot access its contents */
|
||||
#define deadvalue(o) check_exp(ttisdeadkey(o), cast(void *, val_(o).gc))
|
||||
|
||||
#define l_isfalse(o) (ttisnil(o) || (ttisboolean(o) && bvalue(o) == 0))
|
||||
|
||||
|
||||
#define iscollectable(o) (rttype(o) & BIT_ISCOLLECTABLE)
|
||||
|
||||
|
||||
/* Macros for internal tests */
|
||||
#define righttt(obj) (ttype(obj) == gcvalue(obj)->tt)
|
||||
|
||||
#define checkliveness(g,obj) \
|
||||
lua_longassert(!iscollectable(obj) || \
|
||||
(righttt(obj) && !isdead(g,gcvalue(obj))))
|
||||
|
||||
|
||||
/* Macros to set values */
|
||||
#define settt_(o,t) ((o)->tt_=(t))
|
||||
|
||||
#define setfltvalue(obj,x) \
|
||||
{ TValue *io=(obj); val_(io).n=(x); settt_(io, LUA_TNUMFLT); }
|
||||
|
||||
#define setivalue(obj,x) \
|
||||
{ TValue *io=(obj); val_(io).i=(x); settt_(io, LUA_TNUMINT); }
|
||||
|
||||
#define setnilvalue(obj) settt_(obj, LUA_TNIL)
|
||||
|
||||
#define setfvalue(obj,x) \
|
||||
{ TValue *io=(obj); val_(io).f=(x); settt_(io, LUA_TLCF); }
|
||||
|
||||
#define setpvalue(obj,x) \
|
||||
{ TValue *io=(obj); val_(io).p=(x); settt_(io, LUA_TLIGHTUSERDATA); }
|
||||
|
||||
#define setbvalue(obj,x) \
|
||||
{ TValue *io=(obj); val_(io).b=(x); settt_(io, LUA_TBOOLEAN); }
|
||||
|
||||
#define setgcovalue(L,obj,x) \
|
||||
{ TValue *io = (obj); GCObject *i_g=(x); \
|
||||
val_(io).gc = i_g; settt_(io, ctb(i_g->tt)); }
|
||||
|
||||
#define setsvalue(L,obj,x) \
|
||||
{ TValue *io = (obj); TString *x_ = (x); \
|
||||
val_(io).gc = obj2gco(x_); settt_(io, ctb(x_->tt)); \
|
||||
checkliveness(G(L),io); }
|
||||
|
||||
#define setuvalue(L,obj,x) \
|
||||
{ TValue *io = (obj); Udata *x_ = (x); \
|
||||
val_(io).gc = obj2gco(x_); settt_(io, ctb(LUA_TUSERDATA)); \
|
||||
checkliveness(G(L),io); }
|
||||
|
||||
#define setthvalue(L,obj,x) \
|
||||
{ TValue *io = (obj); lua_State *x_ = (x); \
|
||||
val_(io).gc = obj2gco(x_); settt_(io, ctb(LUA_TTHREAD)); \
|
||||
checkliveness(G(L),io); }
|
||||
|
||||
#define setclLvalue(L,obj,x) \
|
||||
{ TValue *io = (obj); LClosure *x_ = (x); \
|
||||
val_(io).gc = obj2gco(x_); settt_(io, ctb(LUA_TLCL)); \
|
||||
checkliveness(G(L),io); }
|
||||
|
||||
#define setclCvalue(L,obj,x) \
|
||||
{ TValue *io = (obj); CClosure *x_ = (x); \
|
||||
val_(io).gc = obj2gco(x_); settt_(io, ctb(LUA_TCCL)); \
|
||||
checkliveness(G(L),io); }
|
||||
|
||||
#define sethvalue(L,obj,x) \
|
||||
{ TValue *io = (obj); Table *x_ = (x); \
|
||||
val_(io).gc = obj2gco(x_); settt_(io, ctb(LUA_TTABLE)); \
|
||||
checkliveness(G(L),io); }
|
||||
|
||||
#define setdeadvalue(obj) settt_(obj, LUA_TDEADKEY)
|
||||
|
||||
|
||||
|
||||
#define setobj(L,obj1,obj2) \
|
||||
{ TValue *io1=(obj1); *io1 = *(obj2); \
|
||||
(void)L; checkliveness(G(L),io1); }
|
||||
|
||||
|
||||
/*
|
||||
** different types of assignments, according to destination
|
||||
*/
|
||||
|
||||
/* from stack to (same) stack */
|
||||
#define setobjs2s setobj
|
||||
/* to stack (not from same stack) */
|
||||
#define setobj2s setobj
|
||||
#define setsvalue2s setsvalue
|
||||
#define sethvalue2s sethvalue
|
||||
#define setptvalue2s setptvalue
|
||||
/* from table to same table */
|
||||
#define setobjt2t setobj
|
||||
/* to table */
|
||||
#define setobj2t setobj
|
||||
/* to new object */
|
||||
#define setobj2n setobj
|
||||
#define setsvalue2n setsvalue
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
** {======================================================
|
||||
** types and prototypes
|
||||
** =======================================================
|
||||
*/
|
||||
|
||||
|
||||
union Value {
|
||||
GCObject *gc; /* collectable objects */
|
||||
void *p; /* light userdata */
|
||||
int b; /* booleans */
|
||||
lua_CFunction f; /* light C functions */
|
||||
lua_Integer i; /* integer numbers */
|
||||
lua_Number n; /* float numbers */
|
||||
};
|
||||
|
||||
|
||||
struct lua_TValue {
|
||||
TValuefields;
|
||||
};
|
||||
|
||||
static void dumpvalue(TValue* v)
|
||||
{
|
||||
// Litle endian assumed
|
||||
for (int i = 7; i >= 0; i--) {
|
||||
printf("%02x", v->tt_.bytes[i]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, const char **argv) {
|
||||
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
|
||||
TValue v = { NILCONSTANT };
|
||||
dumpvalue(&v);
|
||||
assert(ttisnil(&v));
|
||||
|
||||
setivalue(&v, 55);
|
||||
assert(ttisinteger(&v));
|
||||
assert(ttisnumber(&v));
|
||||
assert(ivalue(&v) == 55);
|
||||
|
||||
setfltvalue(&v, 152.76);
|
||||
assert(ttisnumber(&v));
|
||||
assert(ttisfloat(&v));
|
||||
assert(fltvalue(&v) == 152.76);
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,151 +0,0 @@
|
||||
#include <ctype.h>
|
||||
#include <limits.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "lua.h"
|
||||
#include "lauxlib.h"
|
||||
#include "lualib.h"
|
||||
#include "lobject.h"
|
||||
|
||||
/* test supplied lua code compiles */
|
||||
static int test_luacomp1(const char *code)
|
||||
{
|
||||
int rc = 0;
|
||||
lua_State *L;
|
||||
L = luaL_newstate();
|
||||
if (luaL_loadbuffer(L, code, strlen(code), "testfunc") != 0) {
|
||||
rc = 1;
|
||||
fprintf(stderr, "%s\n", lua_tostring(L, -1));
|
||||
lua_pop(L, 1); /* pop error message from the stack */
|
||||
}
|
||||
else
|
||||
ravi_dump_function(L);
|
||||
lua_close(L);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* test supplied lua code compiles */
|
||||
static int test_luacompexec1(const char *code, int expected)
|
||||
{
|
||||
int rc = 0;
|
||||
lua_State *L;
|
||||
L = luaL_newstate();
|
||||
luaL_openlibs(L); /* open standard libraries */
|
||||
if (luaL_loadbuffer(L, code, strlen(code), "testfunc") != 0) {
|
||||
rc = 1;
|
||||
fprintf(stderr, "%s\n", lua_tostring(L, -1));
|
||||
lua_pop(L, 1); /* pop error message from the stack */
|
||||
}
|
||||
else {
|
||||
ravi_dump_function(L);
|
||||
time_t start = time(NULL);
|
||||
if (lua_pcall(L, 0, 1, 0) != 0) {
|
||||
rc = 1;
|
||||
fprintf(stderr, "%s\n", lua_tostring(L, -1));
|
||||
}
|
||||
else {
|
||||
time_t end = time(NULL);
|
||||
ravi_dump_stack(L, "after executing function");
|
||||
printf("time taken = %f\n", difftime(end, start));
|
||||
lua_Integer got = 0;
|
||||
if (lua_isboolean(L, -1))
|
||||
got = lua_toboolean(L, -1) ? 1 : 0;
|
||||
else
|
||||
got = lua_tointeger(L, -1);
|
||||
if (got != expected) {
|
||||
rc = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
lua_close(L);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
static int test_vm()
|
||||
{
|
||||
int failures = 0;
|
||||
failures += test_luacomp1("function x() local t : table = {}; t.name = 'd'; end");
|
||||
failures += test_luacompexec1("function test(); local x: integer = 1; return function (j) x = j; return x; end; end; fn = test(); return fn('55')", 55);
|
||||
failures += test_luacompexec1("ravi.auto(true); function arrayaccess (); local x: integer[] = {5}; return x[1]; end; assert(ravi.compile(arrayaccess)); return arrayaccess()", 5);
|
||||
failures += test_luacompexec1("ravi.auto(true); function cannotload (msg, a,b); assert(not a and string.find(b, msg)); end; ravi.compile(cannotload); return 1", 1);
|
||||
failures += test_luacompexec1("ravi.auto(true); function z(); local a = 5; a = a + 1; return a; end; ravi.compile(z); return z()", 6);
|
||||
failures += test_luacompexec1("ravi.auto(true); function z(x); x[1] = 5; return x[1]; end; ravi.compile(z); return z({})", 5);
|
||||
failures += test_luacompexec1("ravi.auto(true); function z(x,y) return x<y end; ravi.compile(z); return not z(2,1)", 1);
|
||||
failures += test_luacompexec1("ravi.auto(true); local function x(); local d:number = 5.0; return d+5 == 5+d and d-5 == 5-d and d*5 == 5*d; end; local y = x(); return y", 1);
|
||||
failures += test_luacompexec1("ravi.auto(true); function x(f); local i : integer, j : integer = f(); return i + j; end; return ravi.compile(x)", 1);
|
||||
failures += test_luacompexec1("ravi.auto(true); local function z(a); print(a); return a+1; end; local function x(yy); local j = 5; j = yy(j); return j; end; local y = x(z); return y", 6);
|
||||
failures += test_luacompexec1("ravi.auto(true); local function z(a,p); p(a); return 6; end; local function x(yy,p); local j = 5; j = yy(j,p); return j; end; local y = x(z,print); return y", 6);
|
||||
failures += test_luacompexec1("ravi.auto(true); local function x(yy); local j = 5; yy(j); return j; end; local y = x(print); return y", 5);
|
||||
failures += test_luacompexec1("ravi.auto(true); local function x(); local i, j:integer; j=0; for i=1,1000000000 do; j = j+1; end; return j; end; local y = x(); print(y); return y", 1000000000);
|
||||
failures += test_luacompexec1("ravi.auto(true); local function x(); local j:number; for i=1,1000000000 do; j = j+1; end; return j; end; local y = x(); print(y); return y", 1000000000);
|
||||
|
||||
failures += test_luacompexec1("ravi.auto(true); local function x(); local j = 0; for i=2,6,3 do; j = i; end; return j; end; local y = x(); print(y); return y", 5);
|
||||
failures += test_luacompexec1("ravi.auto(true); local function x(); local j = 0; for i=2.0,6.0,3.0 do; j = i; end; return j; end; local y = x(); print(y); return y", 5);
|
||||
failures += test_luacompexec1("ravi.auto(true); local function x(); local a=5; return 1004,2; end; local y; y = x(); print(y); return y", 1004);
|
||||
failures += test_luacompexec1("ravi.auto(true); local function x(); if 1 == 2 then; return 5.0; end; return 1.0; end; local z = x(); print(z); return z", 1);
|
||||
failures += test_luacompexec1("ravi.auto(true); local function x(y); if y == 1 then; return 1.0; elseif y == 5 then; return 2.0; else; return 3.0; end; end; local z = x(5); print(z); return z", 2);
|
||||
failures += test_luacompexec1("ravi.auto(true); local function x(y); if y == 1 then; return 1.0; elseif y == 5 then; return 2.0; else; return 3.0; end; end; local z = x(4); print(z); return z", 3);
|
||||
failures += test_luacompexec1("ravi.auto(true); local function x(y,z); if y == 1 then; if z == 1 then; return 99.0; else; return z; end; elseif y == 5 then; return 2.0; else; return 3.0; end; end; local z = x(1,1); print(z); return z", 99);
|
||||
|
||||
failures += test_luacompexec1("local x:integer[] = {1}; local i:integer = 1; local d:integer = x[i]; x[i] = 5; return d*x[i];", 5);
|
||||
failures += test_luacompexec1("ravi.auto(true); local function x(); local a:number = 1.0; return a+127 == 128.0; end; local y = x(); return y", 1);
|
||||
failures += test_luacompexec1("ravi.auto(true); local function x(); local a:number = 1.0; return a+128 == 129.0; end; local y = x(); return y", 1);
|
||||
failures += test_luacompexec1("ravi.auto(true); local function x(); local a:number = 1.0; return 127+a == 128.0; end; local y = x(); return y", 1);
|
||||
failures += test_luacompexec1("ravi.auto(true); local function x(); local a:number = 1.0; return 128+a == 129.0; end; local y = x(); return y", 1);
|
||||
failures += test_luacompexec1("ravi.auto(true); local function x(); local a:number = 1.0; return a+1.0 == 1.0+a; end; local y = x(); return y", 1);
|
||||
failures += test_luacompexec1("ravi.auto(true); local function x(); local a:integer = 1; return a+127 == 128; end; local y = x(); return y", 1);
|
||||
failures += test_luacompexec1("ravi.auto(true); local function x(); local a:integer = 1; return a+128 == 129; end; local y = x(); return y", 1);
|
||||
failures += test_luacompexec1("ravi.auto(true); local function x(); local a:integer = 1; return 127+a == 128; end; local y = x(); return y", 1);
|
||||
failures += test_luacompexec1("ravi.auto(true); local function x(); local a:integer = 1; return 128+a == 129; end; local y = x(); return y", 1);
|
||||
failures += test_luacompexec1("ravi.auto(true); local function x(); local a:integer = 1; return a+1 == 1+a; end; local y = x(); return y", 1);
|
||||
failures += test_luacompexec1("ravi.auto(true); local function tryme(x); print(#x); return x; end; local da: number[] = { 5, 6 }; da[1] = 42; da = tryme(da); return da[1];", 42);
|
||||
/* following should fail as x is a number[] */
|
||||
failures += test_luacompexec1("ravi.auto(true); local function tryme(x); print(#x); x[1] = 'junk'; return x; end; local da: number[] = {}; da[1] = 42; da = tryme(da); return da[1];", 42) == 1 ? 0 : 1;
|
||||
failures += test_luacomp1("local t = {}; local da : number[] = {}; da=t[1];") == 1 ? 0 : 1;
|
||||
failures += test_luacomp1("local a : integer[] = {}");
|
||||
failures += test_luacompexec1("for i=1,10 do; end; return 0", 0);
|
||||
failures += test_luacompexec1("local a : number[], j:number = {}; for i=1,10 do; a[i] = i; j = j + a[i]; end; return j", 55);
|
||||
failures += test_luacompexec1("local a:integer[] = {}; local i:integer; a[1] = i+5; i = a[1]; return i", 5);
|
||||
failures += test_luacompexec1("local function tryme(); local i,j = 5,6; return i,j; end; local i:integer, j:integer = tryme(); return i+j", 11);
|
||||
failures += test_luacompexec1("local i:integer,j:integer = 1; j = i*j+i; return j", 1);
|
||||
failures += test_luacompexec1("local i:integer; for i=1,10 do; print(i); end; print(i); return i", 0);
|
||||
failures += test_luacomp1("local i:integer, j:number; i,j = f(); j = i*j+i");
|
||||
failures += test_luacomp1("local d; d = f()");
|
||||
failures += test_luacomp1("local d, e; d, e = f(), g()");
|
||||
failures += test_luacomp1("local i:integer, d:number = f()");
|
||||
failures += test_luacomp1("local i:integer,j:number,k:integer = f(), g()");
|
||||
failures += test_luacomp1("local f = function(); return; end; local d:number, j:integer = f(); return d");
|
||||
failures += test_luacomp1("local d = f()");
|
||||
failures += test_luacomp1("return (-1.25 or -4)+0");
|
||||
failures += test_luacomp1("f = nil; local f; function f(a); end");
|
||||
failures += test_luacomp1("local max, min = 0x7fffffff, -0x80000000; assert(string.format(\"%d\", min) == \"-2147483648\"); max, min = 0x7fffffffffffffff, -0x8000000000000000; if max > 2.0 ^ 53 then; end;");
|
||||
failures += test_luacomp1("local function F (m); local function round(m); m = m + 0.04999; return format(\"%.1f\", m);end; end");
|
||||
failures += test_luacomp1("local b:integer = 6; local i:integer = 5+b; return i");
|
||||
failures += test_luacompexec1("local b:integer = 6; local i:integer = 5+b; return i", 11);
|
||||
failures += test_luacomp1("local f = function(); end");
|
||||
failures += test_luacomp1("local b:integer = 6; b = nil; return i") == 0; /* should fail */
|
||||
failures += test_luacomp1("local f = function(); local function y() ; end; end");
|
||||
failures += test_luacompexec1("return -(1 or 2)", -1);
|
||||
failures += test_luacompexec1("return (1 and 2)+(-1.25 or -4) == 0.75", 1);
|
||||
failures += test_luacomp1("local a=1; if a==0 then; a = 2; else a=3; end;");
|
||||
failures += test_luacomp1("local f = function(); return; end; local d:number = 5.0; d = f(); return d");
|
||||
failures += test_luacomp1("local f = function(); return; end; local d = 5.0; d = f(); return d");
|
||||
return failures;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int failures = 0;
|
||||
failures += test_vm();
|
||||
if (failures)
|
||||
printf("FAILED\n");
|
||||
else
|
||||
printf("OK\n");
|
||||
return failures ? 1 : 0;
|
||||
}
|
Loading…
Reference in new issue