Implement EXEC
This commit is contained in:
@@ -2187,8 +2187,49 @@ class Exec : Code
|
|||||||
{
|
{
|
||||||
override void execute(VM vm)
|
override void execute(VM vm)
|
||||||
{
|
{
|
||||||
|
import otya.smilebasic.project;
|
||||||
Value arg;
|
Value arg;
|
||||||
vm.pop(arg);
|
vm.pop(arg);
|
||||||
|
int slot;
|
||||||
|
if (arg.isString)
|
||||||
|
{
|
||||||
|
auto file = Projects.parseFileName(arg.castDString);
|
||||||
|
if (file.resource != Resource.program && file.resource == Resource.none)
|
||||||
|
{
|
||||||
|
throw new IllegalFunctionCall();
|
||||||
|
}
|
||||||
|
if (file.hasResourceNumber && file.resourceNumber >= 4/*?*/)
|
||||||
|
{
|
||||||
|
throw new IllegalFunctionCall();
|
||||||
|
}
|
||||||
|
if (!file.hasResourceNumber)
|
||||||
|
{
|
||||||
|
file.resourceNumber = vm.currentSlotNumber;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
slot = file.resourceNumber;
|
||||||
|
}
|
||||||
|
wstring content;
|
||||||
|
if (vm.petitcomputer.project.loadFile(file.project, "TXT", file.name, content))
|
||||||
|
vm.petitcomputer.slot[slot].load(content);
|
||||||
|
else
|
||||||
|
throw new LoadFailed();//TODO:DIALOG?
|
||||||
|
}
|
||||||
|
else if (arg.isNumber)
|
||||||
|
{
|
||||||
|
slot = arg.castInteger;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new TypeMismatch();
|
||||||
|
}
|
||||||
|
import otya.smilebasic.parser;
|
||||||
|
auto parser = new Parser(cast(immutable)vm.petitcomputer.slot[slot].text);
|
||||||
|
auto compiler = parser.compiler;
|
||||||
|
compiler.compile(vm, slot);
|
||||||
|
vm.setCurrentSlot(slot);
|
||||||
|
vm.pc = 0 - 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1336,6 +1336,13 @@ class Compiler
|
|||||||
registerSystemVariable(vm);
|
registerSystemVariable(vm);
|
||||||
return vm;
|
return vm;
|
||||||
}
|
}
|
||||||
|
void compile(VM vm, int slot)
|
||||||
|
{
|
||||||
|
isDirectMode = false;
|
||||||
|
this.vm = vm;
|
||||||
|
compileProgram();
|
||||||
|
vm.loadSlot(slot, code, globalIndex + 1, global, functions, globalScope.data, globalLabel, debugInfo);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unittest
|
unittest
|
||||||
|
|||||||
@@ -50,6 +50,11 @@ class SyntaxError : SmileBasicError
|
|||||||
}
|
}
|
||||||
class IllegalFunctionCall : SmileBasicError
|
class IllegalFunctionCall : SmileBasicError
|
||||||
{
|
{
|
||||||
|
this()
|
||||||
|
{
|
||||||
|
this.errnum = 4;
|
||||||
|
super("Illegal function call");
|
||||||
|
}
|
||||||
this(string func)
|
this(string func)
|
||||||
{
|
{
|
||||||
this.errnum = 4;
|
this.errnum = 4;
|
||||||
|
|||||||
@@ -164,6 +164,20 @@ struct Slot
|
|||||||
program.insertBack(l ~ '\n');
|
program.insertBack(l ~ '\n');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
wchar[] text()
|
||||||
|
{
|
||||||
|
import std.algorithm.iteration, std.outbuffer;
|
||||||
|
auto buffer = new OutBuffer();
|
||||||
|
buffer.reserve(program.opSlice.map!"(a.length + 1) * 2".sum);
|
||||||
|
|
||||||
|
foreach(line; program)
|
||||||
|
{
|
||||||
|
buffer.write(line);
|
||||||
|
}
|
||||||
|
ubyte[] progbuff = buffer.toBytes;
|
||||||
|
wchar[] progbuff2 = (cast(wchar*)progbuff.ptr)[0..progbuff.length / 2];
|
||||||
|
return progbuff2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
struct Size
|
struct Size
|
||||||
{
|
{
|
||||||
@@ -1046,17 +1060,7 @@ class PetitComputer
|
|||||||
int oldpc;
|
int oldpc;
|
||||||
void runSlot(int lot)
|
void runSlot(int lot)
|
||||||
{
|
{
|
||||||
import std.algorithm.iteration, std.outbuffer;
|
parser = new Parser(cast(wstring)slot[lot].text);
|
||||||
auto buffer = new OutBuffer();
|
|
||||||
buffer.reserve(slot[lot].program.opSlice.map!"(a.length + 1) * 2".sum);
|
|
||||||
|
|
||||||
foreach(line; slot[lot].program)
|
|
||||||
{
|
|
||||||
buffer.write(line);
|
|
||||||
}
|
|
||||||
ubyte[] progbuff = buffer.toBytes;
|
|
||||||
wchar[] progbuff2 = (cast(wchar*)progbuff.ptr)[0..progbuff.length / 2];
|
|
||||||
parser = new Parser(cast(wstring)progbuff2);
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
vm = parser.compile();
|
vm = parser.compile();
|
||||||
|
|||||||
Reference in New Issue
Block a user