Implement SPFUNC
This commit is contained in:
@@ -60,7 +60,33 @@ class VMSlot
|
||||
int backtrace;
|
||||
}
|
||||
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
|
||||
{
|
||||
VMSlot[5] slots;
|
||||
@@ -119,9 +145,9 @@ class VM
|
||||
{
|
||||
if (f.isCommon)
|
||||
{
|
||||
f.isDead = true;
|
||||
commonFunctions.remove(f.name);
|
||||
}
|
||||
f.isDead = true;
|
||||
}
|
||||
auto s = this.slots[slot];
|
||||
s.hasExecReturnAddress = false;
|
||||
@@ -148,7 +174,9 @@ class VM
|
||||
s.globalData = otya.smilebasic.type.Data(gdt, 0);
|
||||
s.globalLabel = globalLabel;
|
||||
s.debugInfo = dinfo;
|
||||
s.unique = unique++;
|
||||
}
|
||||
int unique;
|
||||
Code getCurrent()
|
||||
{
|
||||
return currentSlot.code[pc];
|
||||
@@ -400,9 +428,9 @@ class VM
|
||||
{
|
||||
slot = currentSlot;
|
||||
}
|
||||
if (label in slot.globalLabel)
|
||||
if (name.name in slot.globalLabel)
|
||||
return true;
|
||||
if (currentFunction && label in currentFunction.label)
|
||||
if (currentFunction && name.name in currentFunction.label)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
@@ -422,9 +450,9 @@ class VM
|
||||
{
|
||||
slot = currentSlot;
|
||||
}
|
||||
if (var in slot.globalTable)
|
||||
if (name.name in slot.globalTable)
|
||||
return true;
|
||||
if (currentFunction && var in currentFunction.variable)
|
||||
if (currentFunction && name.name in currentFunction.variable)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
@@ -432,6 +460,47 @@ class VM
|
||||
{
|
||||
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
|
||||
{
|
||||
|
||||
@@ -1883,6 +1883,22 @@ class BuiltinFunction
|
||||
}
|
||||
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)
|
||||
{
|
||||
writeln("NOTIMPL:BGMSTOP");
|
||||
|
||||
@@ -98,7 +98,7 @@ class Function
|
||||
Scope scope_;
|
||||
bool isCommon;
|
||||
VMSlot slot;
|
||||
bool isDead;/*common function*/
|
||||
bool isDead;
|
||||
/**
|
||||
0:bp
|
||||
1:pc
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
module otya.smilebasic.sprite;
|
||||
import otya.smilebasic.petitcomputer;
|
||||
import otya.smilebasic.error;
|
||||
import otya.smilebasic.vm;
|
||||
import derelict.sdl2.sdl;
|
||||
import derelict.opengl3.gl;
|
||||
enum SpriteAttr
|
||||
@@ -191,6 +192,7 @@ struct SpriteData
|
||||
double scalex;
|
||||
double scaley;
|
||||
double r;
|
||||
Callback callback;
|
||||
this(int id)
|
||||
{
|
||||
this.id = id;
|
||||
@@ -1184,4 +1186,9 @@ class Sprite
|
||||
id = spid(id);
|
||||
return sprites[id].define;
|
||||
}
|
||||
void spfunc(int id, Callback callback)
|
||||
{
|
||||
id = spid(id);
|
||||
sprites[id].callback = callback;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user