diff --git a/SMILEBASIC/VM.d b/SMILEBASIC/VM.d index 4aca139..093c9be 100644 --- a/SMILEBASIC/VM.d +++ b/SMILEBASIC/VM.d @@ -34,6 +34,7 @@ class VMSlot Value[] global; VMVariable[wstring] globalTable; Function[wstring] functions; + Function[] functionTable; int[wstring] globalLabel; DebugInfo debugInfo; Value[wstring] directModeVariable; @@ -78,7 +79,7 @@ class VM c.global ~= Value(ValueType.Void); foreach(wstring k, VMVariable v ; globalTable) { - if(v.index >= 0 && v.index >= oldlen) + if(v.index >= 0 && v.index >= oldlen && v.index < c.global.length) c.global[v.index] = Value(v.type); } } diff --git a/SMILEBASIC/builtinfunctions.d b/SMILEBASIC/builtinfunctions.d index 75afbf6..1e3e67a 100644 --- a/SMILEBASIC/builtinfunctions.d +++ b/SMILEBASIC/builtinfunctions.d @@ -7,6 +7,7 @@ import std.traits; import std.stdio; import std.ascii; import std.range; +import std.string; import otya.smilebasic.error; import otya.smilebasic.type; import otya.smilebasic.petitcomputer; @@ -725,7 +726,6 @@ class BuiltinFunction { return str[2..$].to!int(2); } - import std.string : munch; munch(str, " "); if(str.empty) return 0; /* @@ -805,7 +805,6 @@ class BuiltinFunction } static int INSTR(Value vstart, Value vstr1, DefaultValue!(wstring, false) vstr2) { - import std.string; int start = 0; wstring str1, str2; if(!vstr2.isDefault) @@ -1141,7 +1140,6 @@ class BuiltinFunction auto format = args[0].castString; import std.array : appender; import std.format; - import std.string; auto w = appender!wstring(); int j = 1; for(int i = 0; i < format.length; i++) @@ -1311,7 +1309,6 @@ class BuiltinFunction static Value LOAD1(PetitComputer p, wstring name, DefaultValue!(int, false) flag) { import otya.smilebasic.project; - import std.string; flag.setDefaultValue(0); auto type = Projects.splitResourceName(name); wstring txt; @@ -1340,7 +1337,6 @@ class BuiltinFunction static void LOAD2(PetitComputer p, wstring name, DefaultValue!(int, false) flag) { import otya.smilebasic.project; - import std.string; flag.setDefaultValue(0); auto type = Projects.splitResourceName(name); wstring txt; @@ -1399,6 +1395,39 @@ class BuiltinFunction { name = p.currentProject; } + //FILES TYPE$ + //((TXT|DAT):)?\w+/? + static void FILES(PetitComputer p, DefaultValue!(wstring, false) name) + { + import otya.smilebasic.project; + if(name.isDefault) + { + name.setDefaultValue(p.currentProject); + } + auto t = Projects.splitResourceName(name.value); + auto res = t[0]; + if(t[1].length && t[2].length) + { + throw new IllegalFunctionCall("FILES"); + } + if(t[2].length && name.value.indexOf("/") != -1) + { + //"TXT:A":OK + //"TXT:A/":OK + //"TXT:/A":X + //"TXT:A/A":X + throw new IllegalFunctionCall("FILES"); + } + auto project = t[1].length ? t[1] : t[2]; + //project:.->hidden project + //project:/->project list + auto l = p.project.getFileList(project, res); + p.printConsole(res, "\t", project, "\n"); + foreach(i; l) + { + p.printConsole(i, "\n"); + } + } //alias void function(PetitComputer, Value[], Value[]) BuiltinFunc; static BuiltinFunctions[wstring] builtinFunctions; static wstring getBasicName(BFD)(const wstring def) diff --git a/SMILEBASIC/parser.d b/SMILEBASIC/parser.d index 856af56..c8273ee 100644 --- a/SMILEBASIC/parser.d +++ b/SMILEBASIC/parser.d @@ -103,7 +103,7 @@ class Lexical isEmpty = true; //return; }*/ - token = Token(TokenType.Unknown); + token = Token(TokenType.NewLine); return; } int i = index; @@ -789,20 +789,24 @@ class Parser case TokenType.Print: node = print(); return node; + case TokenType.Call: case TokenType.Iden: { wstring name = token.value.stringValue; lex.popFront(); - token = lex.front(); - if(token.type == TokenType.Assign) + if (token.type != TokenType.Call) { - node = assign(name); - return node; - } - if(token.type == TokenType.LBracket)//配列代入 - { - node = arrayAssign(name); - return node; + token = lex.front(); + if(token.type == TokenType.Assign) + { + node = assign(name); + return node; + } + if(token.type == TokenType.LBracket)//配列代入 + { + node = arrayAssign(name); + return node; + } } //命令呼び出し auto func = new CallFunctionStatement(name, lex.location); @@ -932,6 +936,20 @@ class Parser break; case TokenType.Input: return inputStatement(); + case TokenType.Use: + { + lex.popFront(); + auto expr = expression(); + writeln("NOTIMPL:USE"); + } + break; + case TokenType.Exec: + { + lex.popFront(); + auto expr = expression(); + writeln("NOTIMPL:EXEC"); + } + break; default: syntaxError(); break; diff --git a/SMILEBASIC/petitcomputer.d b/SMILEBASIC/petitcomputer.d index 187f83c..6c5ebe0 100644 --- a/SMILEBASIC/petitcomputer.d +++ b/SMILEBASIC/petitcomputer.d @@ -924,6 +924,7 @@ class PetitComputer glAlphaFunc(GL_GEQUAL, 0.1f); glEnable(GL_ALPHA_TEST); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + xscreen(0, 512, 4); while(true) { auto profile = SDL_GetTicks(); @@ -1111,7 +1112,7 @@ class PetitComputer } void printPrompt() { - //printConsole("[","]"); + if(currentProject.length) printConsole("[", currentProject, "]"); printConsole("OK\n"); } Slot[] slot; @@ -1449,7 +1450,7 @@ class PetitComputer wstring input(wstring prompt, bool useClipBoard) { auto olddisplay = displaynum; - displaynum = 0; + //displaynum = 0; printConsole(prompt); clearKeyBuffer(); wstring buffer; @@ -1517,7 +1518,7 @@ class PetitComputer } } showCursor = false; - display = olddisplay; + //display = olddisplay; return buffer; } int CSRX; @@ -1741,7 +1742,7 @@ class PetitComputer glVertex3f(x * 8 + 8, y * 8 + 8, 1024); } } - if(showCursor && animationCursor) + if(displaynum == 0 && showCursor && animationCursor) { glColor4ubv(cast(ubyte*)&consoleColorGL[15]); glVertex3f((CSRX * 8), (CSRY * 8 + 8), -256); @@ -1792,7 +1793,7 @@ class PetitComputer glVertex3f(x * 8 + 8, y * 8 + 8, 1024); } } - if(showCursor && animationCursor) + if(displaynum == 1 && showCursor && animationCursor) { glColor4ubv(cast(ubyte*)&consoleColorGL[15]); glVertex3f((CSRX * 8), (CSRY * 8 + 8), -256); diff --git a/SMILEBASIC/project.d b/SMILEBASIC/project.d index 7c74def..ef70adb 100644 --- a/SMILEBASIC/project.d +++ b/SMILEBASIC/project.d @@ -1,4 +1,5 @@ module otya.smilebasic.project; +import otya.smilebasic.error; import std.path; import std.file; import std.string; @@ -6,6 +7,7 @@ import std.traits; import std.conv; import std.uni; import std.typecons; +import std.range; class Projects { wstring rootPath; @@ -30,7 +32,7 @@ class Projects createProjectInternal("[DEFAULT]"); createProjectInternal("SYS"); } - bool isValidProjectName(C)(C[] filename) if(isSomeChar!(C)) + static bool isValidProjectName(C)(C[] filename) if(isSomeChar!(C)) { if(filename.length > 14) { @@ -45,7 +47,7 @@ class Projects } return true; } - bool isValidFileName(C)(C[] filename) if(isSomeChar!(C)) + static bool isValidFileName(C)(C[] filename) if(isSomeChar!(C)) { if(filename.length > 12) { @@ -95,6 +97,36 @@ class Projects } return tuple(type, project, name); } + wstring[] getFileList(wstring project, wstring type) + { + import std.algorithm; + import std.functional; + if(!isValidProjectName(project)) + { + return null; + } + if(project == "") project = "[DEFAULT]"; + auto dir(wstring type) + { + auto path = buildPath(projectPath, project, type).to!string; + return dirEntries(path, SpanMode.shallow, false); + } + + if(type == "") + { + return chain(dir("TXT").filter!(x=>x.isFile&&isValidFileName(baseName(x.name))).map!((x) => "*"w ~ baseName(x.name).to!wstring), + dir("DAT").filter!(x=>x.isFile&&isValidFileName(baseName(x.name))).map!((x) => " " ~ baseName(x.name).to!wstring)).array; + } + if(type == "TXT") + { + return dir("TXT").filter!(x=>x.isFile&&isValidFileName(baseName(x.name))).map!((x) => "*" ~ baseName(x.name).to!wstring).array; + } + if(type == "DAT") + { + return dir("DAT").filter!(x=>x.isFile&&isValidFileName(baseName(x.name))).map!((x) => " " ~ baseName(x.name).to!wstring).array; + } + return null; + } bool loadFile(wstring project, wstring type, wstring name, out wstring contents) { contents = ""; diff --git a/SMILEBASIC/token.d b/SMILEBASIC/token.d index df4dadf..35277f3 100644 --- a/SMILEBASIC/token.d +++ b/SMILEBASIC/token.d @@ -65,6 +65,9 @@ enum TokenType Input, True, False, + Use, + Exec, + Call, } struct Token diff --git a/SMILEBASIC/type.d b/SMILEBASIC/type.d index 3a6f4fc..dfa5ca8 100644 --- a/SMILEBASIC/type.d +++ b/SMILEBASIC/type.d @@ -182,6 +182,8 @@ struct Value } } } +//import std.experimental.ndslice; +//ndsliceがこれに相当? class Array(T) { T[] array;