Implement SPFUNC
This commit is contained in:
@@ -60,7 +60,33 @@ class VMSlot
|
|||||||
int backtrace;
|
int backtrace;
|
||||||
}
|
}
|
||||||
ExecData execData;
|
ExecData execData;
|
||||||
|
//This value is changed each time slot is used.
|
||||||
|
size_t unique;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum CallbackType
|
||||||
|
{
|
||||||
|
none,
|
||||||
|
label,
|
||||||
|
function_,
|
||||||
|
}
|
||||||
|
struct Callback
|
||||||
|
{
|
||||||
|
CallbackType type;
|
||||||
|
Function func;
|
||||||
|
VMSlot slot;
|
||||||
|
size_t slotUnique;
|
||||||
|
int label;
|
||||||
|
bool isCallable()
|
||||||
|
{
|
||||||
|
if (type == CallbackType.label)
|
||||||
|
return slot.unique == slotUnique;
|
||||||
|
if (type == CallbackType.function_)
|
||||||
|
return func.isDead;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class VM
|
class VM
|
||||||
{
|
{
|
||||||
VMSlot[5] slots;
|
VMSlot[5] slots;
|
||||||
@@ -119,9 +145,9 @@ class VM
|
|||||||
{
|
{
|
||||||
if (f.isCommon)
|
if (f.isCommon)
|
||||||
{
|
{
|
||||||
f.isDead = true;
|
|
||||||
commonFunctions.remove(f.name);
|
commonFunctions.remove(f.name);
|
||||||
}
|
}
|
||||||
|
f.isDead = true;
|
||||||
}
|
}
|
||||||
auto s = this.slots[slot];
|
auto s = this.slots[slot];
|
||||||
s.hasExecReturnAddress = false;
|
s.hasExecReturnAddress = false;
|
||||||
@@ -148,7 +174,9 @@ class VM
|
|||||||
s.globalData = otya.smilebasic.type.Data(gdt, 0);
|
s.globalData = otya.smilebasic.type.Data(gdt, 0);
|
||||||
s.globalLabel = globalLabel;
|
s.globalLabel = globalLabel;
|
||||||
s.debugInfo = dinfo;
|
s.debugInfo = dinfo;
|
||||||
|
s.unique = unique++;
|
||||||
}
|
}
|
||||||
|
int unique;
|
||||||
Code getCurrent()
|
Code getCurrent()
|
||||||
{
|
{
|
||||||
return currentSlot.code[pc];
|
return currentSlot.code[pc];
|
||||||
@@ -400,9 +428,9 @@ class VM
|
|||||||
{
|
{
|
||||||
slot = currentSlot;
|
slot = currentSlot;
|
||||||
}
|
}
|
||||||
if (label in slot.globalLabel)
|
if (name.name in slot.globalLabel)
|
||||||
return true;
|
return true;
|
||||||
if (currentFunction && label in currentFunction.label)
|
if (currentFunction && name.name in currentFunction.label)
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -422,9 +450,9 @@ class VM
|
|||||||
{
|
{
|
||||||
slot = currentSlot;
|
slot = currentSlot;
|
||||||
}
|
}
|
||||||
if (var in slot.globalTable)
|
if (name.name in slot.globalTable)
|
||||||
return true;
|
return true;
|
||||||
if (currentFunction && var in currentFunction.variable)
|
if (currentFunction && name.name in currentFunction.variable)
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -432,6 +460,47 @@ class VM
|
|||||||
{
|
{
|
||||||
return slot >= 0 && slot < slotSize;
|
return slot >= 0 && slot < slotSize;
|
||||||
}
|
}
|
||||||
|
Callback createCallback(wstring funcOrLabel)
|
||||||
|
{
|
||||||
|
Callback result;
|
||||||
|
result.type = CallbackType.none;
|
||||||
|
import otya.smilebasic.builtinfunctions;
|
||||||
|
auto name = parse(funcOrLabel);
|
||||||
|
VMSlot slot;
|
||||||
|
if (name.hasSlot)
|
||||||
|
{
|
||||||
|
if (!checkSlotNumber(name.slot))
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
slot = slots[name.slot];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
slot = currentSlot;
|
||||||
|
}
|
||||||
|
result.slot = slot;
|
||||||
|
result.slotUnique = slot.unique;
|
||||||
|
Function func;
|
||||||
|
func = slot.functions.get(name.name, null);
|
||||||
|
if (func is null)
|
||||||
|
func = commonFunctions.get(name.name, null);
|
||||||
|
if (func)
|
||||||
|
{
|
||||||
|
result.type = CallbackType.function_;
|
||||||
|
result.func = func;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
//global only
|
||||||
|
int label = slot.globalLabel.get(name.name, int.min);
|
||||||
|
if (label == int.min)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
result.type = CallbackType.label;
|
||||||
|
result.label = label;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
enum CodeType
|
enum CodeType
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1883,6 +1883,22 @@ class BuiltinFunction
|
|||||||
}
|
}
|
||||||
return p.sprite.spused(id);
|
return p.sprite.spused(id);
|
||||||
}
|
}
|
||||||
|
static void SPFUNC(PetitComputer p, int id, wstring func)
|
||||||
|
{
|
||||||
|
if (!p.sprite.isValidSpriteId(id))
|
||||||
|
{
|
||||||
|
throw new OutOfRange("SPFUNC", 1);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
if (!p.sprite.isSpriteDefined(id))
|
||||||
|
{
|
||||||
|
throw new IllegalFunctionCall("SPFUNC", 1);
|
||||||
|
}*/
|
||||||
|
auto callback = p.vm.createCallback(func);
|
||||||
|
if (callback.type == CallbackType.none)
|
||||||
|
throw new IllegalFunctionCall("SPFUNC"/*, 2*/);
|
||||||
|
p.sprite.spfunc(id, callback);
|
||||||
|
}
|
||||||
static void BGMSTOP(PetitComputer p)
|
static void BGMSTOP(PetitComputer p)
|
||||||
{
|
{
|
||||||
writeln("NOTIMPL:BGMSTOP");
|
writeln("NOTIMPL:BGMSTOP");
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ class Function
|
|||||||
Scope scope_;
|
Scope scope_;
|
||||||
bool isCommon;
|
bool isCommon;
|
||||||
VMSlot slot;
|
VMSlot slot;
|
||||||
bool isDead;/*common function*/
|
bool isDead;
|
||||||
/**
|
/**
|
||||||
0:bp
|
0:bp
|
||||||
1:pc
|
1:pc
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
module otya.smilebasic.sprite;
|
module otya.smilebasic.sprite;
|
||||||
import otya.smilebasic.petitcomputer;
|
import otya.smilebasic.petitcomputer;
|
||||||
import otya.smilebasic.error;
|
import otya.smilebasic.error;
|
||||||
|
import otya.smilebasic.vm;
|
||||||
import derelict.sdl2.sdl;
|
import derelict.sdl2.sdl;
|
||||||
import derelict.opengl3.gl;
|
import derelict.opengl3.gl;
|
||||||
enum SpriteAttr
|
enum SpriteAttr
|
||||||
@@ -191,6 +192,7 @@ struct SpriteData
|
|||||||
double scalex;
|
double scalex;
|
||||||
double scaley;
|
double scaley;
|
||||||
double r;
|
double r;
|
||||||
|
Callback callback;
|
||||||
this(int id)
|
this(int id)
|
||||||
{
|
{
|
||||||
this.id = id;
|
this.id = id;
|
||||||
@@ -1184,4 +1186,9 @@ class Sprite
|
|||||||
id = spid(id);
|
id = spid(id);
|
||||||
return sprites[id].define;
|
return sprites[id].define;
|
||||||
}
|
}
|
||||||
|
void spfunc(int id, Callback callback)
|
||||||
|
{
|
||||||
|
id = spid(id);
|
||||||
|
sprites[id].callback = callback;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user