1
0

CALLを実装

This commit is contained in:
otya128
2016-08-31 16:46:11 +09:00
parent 4015f6be43
commit e9c94f5bbd
5 changed files with 132 additions and 12 deletions

View File

@@ -1,11 +1,11 @@
TABSTEP=4
FOR i=0 TO 20
?"A","B",
NEXT
SPSET 0,1206
SPANIM 0,"I",-90,1209,0
WHILE 1
WEND
DEF CALLTEST(V)
RETURN V
END
CALL "SPDEF",1192 OUT A,B
ASSERT__ A==464, "CALLTEST"
ASSERT__ B==384, "CALLTEST"
ASSERT__ CALL("CALLTEST", TRUE), "CALLTEST"
DEF TESST X,A$
IF Y<0 THEN Y=28
IF X<0 THEN X=20-(LEN(A$)/2)

View File

@@ -1124,6 +1124,114 @@ class CallFunctionCode : Code
return "callfunc " ~ name.to!string;
}
}
class CallFunctionS : Code
{
int argCount;
int outArgCount;
this(int argCount, int outArgCount)
{
this.argCount = argCount;
this.outArgCount = outArgCount;
}
void callBuintinFunc(BuiltinFunction func, VM vm)
{
Value[] arg;
Value[] oldresult;
Value[] result;
arg = vm.stack[vm.stacki - argCount..vm.stacki];
result = vm.stack[vm.stacki/* - argcount */+ 1..vm.stacki + 1/* - argcount */+ outArgCount];//雑;
oldresult = result;
if (argCount != func.argments.length && func.hasSkipArgument)
{
auto newarg = new Value[func.argments.length];
newarg[$ - argCount .. $] = arg[0..$];
arg = newarg;
}
if (outArgCount != func.results.length)
{
auto newarg = new Value[func.results.length];
newarg[$ - outArgCount .. $] = result[0..$];
result = newarg;
}
func.func(vm.petitcomputer, arg, result);
if(func.variadic)
{
vm.stacki -= argCount;
}
else
{
vm.stacki -= func.argments.length;// - outcount;
}
////vm.stacki += outcount;
//vm.stacki = old;
for(int i = 0; i < outArgCount; i++)
{
vm.push(result[i]);
}
}
void callFunc(Function func, VM vm)
{
if(func.argCount != this.argCount)
{
throw new IllegalFunctionCall(func.name.to!string);
}
if(func.outArgCount != this.outArgCount)
{
throw new IllegalFunctionCall(func.name.to!string);
}
//TODO:args
auto bp = vm.stacki;
vm.push(Value());
vm.push(Value(vm.bp));
vm.pushpc;//vm.push(Value(vm.pc));
vm.bp = bp;
vm.pc = func.address - 1;
vm.stacki += func.variableIndex - 1;
foreach(wstring k, VMVariable v ; func.variable)
{
if(v.index > 0)
{
vm.stack[bp + v.index] = Value(v.type);
}
}
}
override void execute(VM vm)
{
Value vname;
vm.pop(vname);
if (!vname.isString)
{
throw new TypeMismatch();
}
auto name = vname.castString;
Function func = vm.currentSlot.functions.get(name, null);
if(!func)
{
auto bfuncs = otya.smilebasic.builtinfunctions.BuiltinFunction.builtinFunctions.get(name, null);
if (!bfuncs)
{
throw new SyntaxError(name);
}
auto bfunc = bfuncs.overloadResolution(argCount, outArgCount);
/* if(bfunc.argments.length >= argCount)
{
auto k = bfunc.argments.length - argCount;
foreach(l;0..k)
{
vm.push(Value(ValueType.Void));
}
}*/
callBuintinFunc(bfunc, vm);
return;
}
callFunc(func, vm);
}
override string toString(VM vm)
{
return "callfuncS " ~ argCount.to!string ~ "," ~ outArgCount.to!string;
}
}
import otya.smilebasic.builtinfunctions;
class CallBuiltinFunction : Code
{

View File

@@ -496,9 +496,16 @@ class Compiler
{
genCode(new CallBuiltinFunction(bfun, cast(int)func.args.length, 1));
}
else if (func.name == "CALL")
{
if (func.args.length < 1)
{
throw new SyntaxError();
}
genCode(new CallFunctionS((cast(int)func.args.length) - 1, 1));
}
else
{
writeln(func.name);
genCode(new CallFunctionCode(func.name, cast(int)func.args.length));
}
}
@@ -911,9 +918,12 @@ class Compiler
{
genCode(new CallBuiltinFunction(bfun, cast(int)func.args.length, cast(int)bfun.results.length));//func.outVariable.length));
}
else if (func.name == "CALL")
{
genCode(new CallFunctionS((cast(int)func.args.length) - 1, cast(int)func.outVariable.length));
}
else
{
writeln(func.name);
genCode(new CallFunctionCode(func.name, cast(int)func.args.length, cast(int)func.outVariable.length));
}
if(bfun)

View File

@@ -74,6 +74,7 @@ class Lexical
reserved["INPUT"] = TokenType.Input;
reserved["TRUE"] = TokenType.True;
reserved["FALSE"] = TokenType.False;
reserved["CALL"] = TokenType.Call;
reserved.rehash();
}
this(wstring input)
@@ -184,7 +185,7 @@ class Lexical
}
if(r != TokenType.Unknown)
{
token = Token(r);
token = Token(r, Value(iden));
break;
}
}
@@ -1522,6 +1523,7 @@ class Parser
version(none)stdout.flush();
node = new Constant(token.value, lex.location);
break;
case TokenType.Call:
case TokenType.Iden:
if(!lex.empty())
lex.popFront();

View File

@@ -1175,7 +1175,7 @@ class PetitComputer
//デバッグ用
version(NDirectMode)
{
slot[0].load(readText("./SYS/EX8TECDEMO.TXT").to!wstring);
slot[0].load(readText("./TEST.TXT").to!wstring);
version(none)
parser = new Parser(
//readText("./SYS/GAME6TALK.TXT").to!wstring