From 5dff13b64ff86c102e0ff69dadbc57edc515c202 Mon Sep 17 00:00:00 2001 From: otya128 Date: Mon, 13 Jul 2015 21:39:42 +0900 Subject: [PATCH] =?UTF-8?q?=E9=96=A2=E6=95=B0=E5=86=85=E3=83=A9=E3=83=99?= =?UTF-8?q?=E3=83=AB=E5=AE=9F=E8=A3=85=E3=81=A8=E5=BC=95=E6=95=B0=E3=81=AA?= =?UTF-8?q?=E3=81=97=E9=96=A2=E6=95=B0=E3=82=92=E6=AD=A3=E5=B8=B8=E3=81=AB?= =?UTF-8?q?=E5=91=BC=E3=81=B9=E3=82=8B=E3=82=88=E3=81=86=E3=81=AB=E3=81=97?= =?UTF-8?q?=E3=81=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SMILEBASIC/TEST.txt | 12 +++++++ SMILEBASIC/VM.d | 14 +++++--- SMILEBASIC/builtinfunctions.d | 20 ++++++++++- SMILEBASIC/compiler.d | 65 +++++++++++++++++++++++++++++----- SMILEBASIC/node.d | 16 +++++++++ SMILEBASIC/parser.d | 66 +++++++++++++++++++++++++++-------- SMILEBASIC/petitcomputer.d | 66 +++++++++++++++++++++++++---------- SMILEBASIC/token.d | 3 ++ 8 files changed, 215 insertions(+), 47 deletions(-) diff --git a/SMILEBASIC/TEST.txt b/SMILEBASIC/TEST.txt index 417baa7..3999c53 100644 --- a/SMILEBASIC/TEST.txt +++ b/SMILEBASIC/TEST.txt @@ -24,6 +24,18 @@ DEF INCTEST A DEC A ASSERT__ A==10, "A==10" END +GOTOTEST +GOTO@SKIP +@LOCAL +ASSERT__ 0, "LOCAL LABEL" +@SKIP +DEF GOTOTEST + GOTO @LOCAL + ASSERT__ 0, "LOCAL LABEL" + @LOCAL +END +@DATA_1 +DATA "A",1,2,3,4 LOCATE 10, COLOR 1,15 PRINT "テスト正常終了" \ No newline at end of file diff --git a/SMILEBASIC/VM.d b/SMILEBASIC/VM.d index 8a6f819..2d74fd2 100644 --- a/SMILEBASIC/VM.d +++ b/SMILEBASIC/VM.d @@ -486,14 +486,16 @@ class GotoAddr : Code class GotoS : Code { wstring label; - this(wstring label) + Scope sc; + this(wstring label, Scope sc) { this.type = CodeType.GotoS; this.label = label; + this.sc = sc; } override void execute(VM vm) { - stderr.writeln("can't execute"); + stderr.writeln("can't execute (compiler bug?)"); } } class GotoTrue : Code @@ -545,14 +547,16 @@ class GosubAddr : Code class GosubS : Code { wstring label; - this(wstring label) + Scope sc; + this(wstring label, Scope sc) { this.type = CodeType.GosubS; this.label = label; + this.sc = sc; } override void execute(VM vm) { - stderr.writeln("can't execute"); + stderr.writeln("can't execute (compiler bug?)"); } } class ReturnSubroutine : Code @@ -829,7 +833,7 @@ class CallFunctionCode : Code } override void execute(VM vm) { - Function func = vm.functions[name]; + Function func = vm.functions.get(name, null); if(!func) { throw new SyntaxError(); diff --git a/SMILEBASIC/builtinfunctions.d b/SMILEBASIC/builtinfunctions.d index 0ba6147..7affb3c 100644 --- a/SMILEBASIC/builtinfunctions.d +++ b/SMILEBASIC/builtinfunctions.d @@ -102,6 +102,20 @@ class BuiltinFunction } assert(cond, message.to!string); } + static int BUTTON(PetitComputer p, DefaultValue!(int, false) mode) + { + return 0; + } + static void VISIBLE(PetitComputer p, DefaultValue!(int) console, DefaultValue!(int) graphic, DefaultValue!(int) BG, DefaultValue!(int) sprite) + { + } + static void XSCREEN(PetitComputer p, int mode, DefaultValue!(int, false) a, DefaultValue!(int, false) b) + { + } + static void DISPLAY(PetitComputer p, DefaultValue!(int) display) + { + } + //alias void function(PetitComputer, Value[], Value[]) BuiltinFunc; static BuiltinFunction[wstring] builtinFunctions; static this() @@ -148,6 +162,10 @@ template GetFunctionReturnType(T, string N) { enum GetFunctionReturnType = ValueType.Double; } + else static if(is(ReturnType!(__traits(getMember, T, N)) == int)) + { + enum GetFunctionReturnType = ValueType.Integer; + } else static if(is(ReturnType!(__traits(getMember, T, N)) == void)) { enum GetFunctionReturnType = ValueType.Void; @@ -160,7 +178,7 @@ template GetFunctionReturnType(T, string N) } template AddFunc(T, string N) { - static if(is(ReturnType!(__traits(getMember, T, N)) == double)) + static if(is(ReturnType!(__traits(getMember, T, N)) == double) || is(ReturnType!(__traits(getMember, T, N)) == int)) { const string AddFunc = "function void(PetitComputer p, Value[] arg, Value[] ret){if(ret.length != 1){throw new IllegalFunctionCall();}ret[0] = Value(" ~ N ~ "(" ~ AddFuncArg!(ParameterTypeTuple!(__traits(getMember, T, N)).length - 1, 0, 0, ParameterTypeTuple!(__traits(getMember, T, N))) ~ "));}"; diff --git a/SMILEBASIC/compiler.d b/SMILEBASIC/compiler.d index 9bdd643..696ba24 100644 --- a/SMILEBASIC/compiler.d +++ b/SMILEBASIC/compiler.d @@ -10,20 +10,37 @@ class Scope GotoAddr breakAddr; GotoAddr continueAddr; Function func; + DataTable data; this() { + this.data = new DataTable(); } this(GotoAddr breakAddr, GotoAddr continueAddr, Scope parent) { this.breakAddr = breakAddr; this.continueAddr = continueAddr; this.func = parent.func; + this.data = parent.data; } this(Function func) { + this(); this.func = func; } } +class DataTable +{ + Value[] data; + int[wstring] label; + void addData(Value data) + { + this.data ~= data; + } + void addLabel(wstring label) + { + this.label[label] = data.length; + } +} class Function { int address; @@ -185,13 +202,13 @@ class Compiler { code ~= new Operate(op); } - void genCodeGoto(wstring label) + void genCodeGoto(wstring label, Scope sc) { - code ~= new GotoS(label); + code ~= new GotoS(label, sc); } - void genCodeGosub(wstring label) + void genCodeGosub(wstring label, Scope sc) { - code ~= new GosubS(label); + code ~= new GosubS(label, sc); } GotoAddr genCodeGoto() { @@ -554,12 +571,19 @@ class Compiler case NodeType.Label: { auto label = cast(Label)i; - globalLabel[label.label] = code.length; + if(s.func) + { + s.func.label[label.label] = code.length; + } + else + { + globalLabel[label.label] = code.length; + } } break; case NodeType.Goto: { - genCodeGoto((cast(Goto)i).label); + genCodeGoto((cast(Goto)i).label, s); } break; case NodeType.If: @@ -571,7 +595,7 @@ class Compiler case NodeType.Gosub: { auto gosub = cast(Gosub)i; - genCodeGosub(gosub.label); + genCodeGosub(gosub.label, s); } break; case NodeType.Return: @@ -666,6 +690,13 @@ class Compiler case NodeType.Inc: compileInc(cast(Inc)i, s); break; + case NodeType.Data: + { + auto data = cast(Data)i; + foreach(j; data.data) + s.data.addData(j); + } + break; default: stderr.writeln("Compile:NotImpl ", i.type); } @@ -686,11 +717,27 @@ class Compiler { if(c.type == CodeType.GotoS) { - code[i] = new GotoAddr(globalLabel[(cast(GotoS)c).label]); + auto label = cast(GotoS)c; + if(label.sc.func) + { + code[i] = new GotoAddr(label.sc.func.label[label.label]); + } + else + { + code[i] = new GotoAddr(globalLabel[label.label]); + } } if(c.type == CodeType.GosubS) { - code[i] = new GosubAddr(globalLabel[(cast(GosubS)c).label]); + auto label = cast(GosubS)c; + if(label.sc.func) + { + code[i] = new GosubAddr(label.sc.func.label[label.label]); + } + else + { + code[i] = new GosubAddr(globalLabel[label.label]); + } } } return new VM(code, globalIndex + 1, global, functions); diff --git a/SMILEBASIC/node.d b/SMILEBASIC/node.d index 53f71d8..8fb808d 100644 --- a/SMILEBASIC/node.d +++ b/SMILEBASIC/node.d @@ -36,6 +36,9 @@ enum NodeType DefineFunction, While, Inc, + Data, + Read, + Restore, } abstract class Node { @@ -432,3 +435,16 @@ class Inc : Statement this.expression = expr; } } +class Data : Statement +{ + Value[] data; + this() + { + this.type = NodeType.Data; + this.data = new Value[0]; + } + void addData(Value v) + { + data ~= v; + } +} diff --git a/SMILEBASIC/parser.d b/SMILEBASIC/parser.d index bf72b57..3848e5e 100644 --- a/SMILEBASIC/parser.d +++ b/SMILEBASIC/parser.d @@ -64,6 +64,9 @@ class Lexical reserved["WEND"] = TokenType.WEnd; reserved["INC"] = TokenType.Inc; reserved["DEC"] = TokenType.Dec; + reserved["DATA"] = TokenType.Data; + reserved["READ"] = TokenType.Read; + reserved["RESTORE"] = TokenType.Restore; reserved.rehash(); line = 1; } @@ -168,7 +171,7 @@ class Lexical for(;i < code.length;i++) { c = code[i]; - if(!c.isAlpha()) + if(!c.isAlpha() && !c.isDigit() && c != '_') { break; } @@ -506,21 +509,25 @@ class Parser else { //MEMO:引数に[]を付けようが扱いは同一 - while(true) + token = lex.front(); + if(token.type == TokenType.Iden) { - wstring arg = getFunctionArgument(); - if(arg.length == 0) + while(true) { - return null; + wstring arg = getFunctionArgument(); + if(arg.length == 0) + { + return null; + } + node.addArgument(arg); + token = lex.front(); + if(token.type == TokenType.Comma) + { + lex.popFront(); + continue; + } + break; } - node.addArgument(arg); - token = lex.front(); - if(token.type == TokenType.Comma) - { - lex.popFront(); - continue; - } - break; } if(token.type == TokenType.Out) { @@ -680,7 +687,11 @@ class Parser token = lex.front(); } else - func.addArg(expression()); + { + auto expr = expression(); + if(expr) + func.addArg(expr); + } if(lex.front().type != TokenType.Comma) break; lex.popFront(); } @@ -772,6 +783,8 @@ class Parser case TokenType.Inc: case TokenType.Dec: return incStatement(); + case TokenType.Data: + return dataStatement(); default: syntaxError(); break; @@ -779,6 +792,31 @@ class Parser lex.popFront(); return node; } + Data dataStatement() + { + Data data = new Data(); + lex.popFront(); + auto token = lex.front(); + while(true) + { + if(token.type != TokenType.String && token.type != TokenType.Integer) + { + syntaxError(); + return null; + } + data.addData(token.value); + lex.popFront(); + token = lex.front(); + if(token.type == TokenType.Comma) + { + lex.popFront(); + token = lex.front(); + continue; + } + break; + } + return data; + } Inc incStatement() { auto token = lex.front(); diff --git a/SMILEBASIC/petitcomputer.d b/SMILEBASIC/petitcomputer.d index 55c049d..3be4a03 100644 --- a/SMILEBASIC/petitcomputer.d +++ b/SMILEBASIC/petitcomputer.d @@ -75,6 +75,8 @@ class PetitComputer GraphicPage GRPF; GraphicPage[] GRPFColor; GraphicPage[][] GRPFColorFore; + SDL_Surface* s8x8; + SDL_Texture* t8x8; //PNG画像から透過色のpixelを指定して透過しGRPを作る GraphicPage createGraphicPage(string file, int pixel) { @@ -223,12 +225,22 @@ class PetitComputer fontFile); } GRPF = createGraphicPage(fontFile, 0); - GRPFColor = new GraphicPage[consoleColor.length]; - GRPFColorFore = new GraphicPage[][consoleColor.length]; - for(int i = 0; i < GRPFColor.length; i++) + s8x8 = SDL_CreateRGBSurface(0, 8, 8, 32, 0, 0, 0, 0); + auto pixels = (cast(uint*)s8x8.pixels); + for(int x = 0; x < 8; x++) { - GRPFColor[i] = createGRPF(i, GRPF.surface); + for(int y = 0; y < 8; y++) + { + *pixels = SDL_MapRGBA(s8x8.format, 255, 255, 255, 255); + pixels++; + } } + //GRPFColor = new GraphicPage[consoleColor.length]; + //GRPFColorFore = new GraphicPage[][consoleColor.length]; + //for(int i = 0; i < GRPFColor.length; i++) + //{ + // GRPFColor[i] = createGRPF(i, GRPF.surface); + //} /+for(int i = 0; i < GRPFColor.length; i++) { GRPFColorFore[i] = new GraphicPage[consoleColor.length]; @@ -289,6 +301,9 @@ class PetitComputer vsyncCount = 0; vsyncFrame = f; } + int keybufferpos; + //解析した結果キー入力のバッファは127くらい + wchar[] keybuffer = new wchar[127]; void render() { bool renderprofile; @@ -299,10 +314,11 @@ class PetitComputer SDL_WINDOW_SHOWN); renderer = SDL_CreateRenderer(window, -1, 0); GRPF.createTexture(renderer); - for(int i = 0; i < GRPFColor.length; i++) + /*for(int i = 0; i < GRPFColor.length; i++) { GRPFColor[i].createTexture(renderer); - } + }*/ + t8x8 = SDL_CreateTextureFromSurface(renderer, s8x8); write("OK!"); SDL_Event event; while(true) @@ -313,7 +329,6 @@ class PetitComputer renderConsole; SDL_RenderPresent(renderer); auto a = (SDL_GetTicks() - profile); - if(renderprofile) writeln(a); while (SDL_PollEvent(&event)) { switch (event.type) @@ -322,11 +337,16 @@ class PetitComputer SDL_DestroyWindow(window); SDL_Quit(); return; - + case SDL_KEYDOWN: + auto key = event.key.keysym.sym; + keybuffer[keybufferpos] = cast(wchar)key; + keybufferpos = (keybufferpos + 1) % keybuffer.length; + break; default: break; } } + if(!renderprofile) writeln(a); } } catch(Throwable t) @@ -347,8 +367,10 @@ class PetitComputer } }+/ //とりあえず - auto parser = new Parser(readText("TEST.TXT").to!wstring/*readText("FIZZBUZZ.TXT").to!wstring*//*" -?ABS(-1) + auto parser = new Parser(//readText("./SYS/EX1TEXT.TXT").to!wstring + //readText("FIZZBUZZ.TXT").to!wstring + readText("TEST.TXT").to!wstring +/*"?ABS(-1) LOCATE 0,10 COLOR 5 FOR I=0 TO 10 @@ -357,12 +379,9 @@ NEXT DEF FACT(N) IF N<=1 THEN RETURN 1 RETURN N*FACT(N-1) -END"*//* +END"*/ +/* `CLS : CL=0 : Z=0 -WHILE 1 -INC Z,2 -?Z, -WEND WHILE 1 INC Z : IF Z>200 THEN Z=0 FOR I=0 TO 15 @@ -370,7 +389,8 @@ WHILE 1 PRINT "★ 梅雨で雨が多い季節ですね ★" NEXT CL=(CL+1) MOD 16 : VSYNC 2 -WEND`*//* +WEND`*/ +/* `CLS : CL=0 WHILE 1 FOR I=0 TO 15 @@ -436,6 +456,11 @@ GOTO @LOOP`*/ SDL_DestroyWindow(window); SDL_Quit(); } + wstring input(wstring prompt, bool useClipBoard) + { + printConsole(prompt); + return ""; + } int CSRX; int CSRY; int CSRZ; @@ -449,10 +474,15 @@ GOTO @LOOP`*/ for(int x = 0; x < consoleWidth; x++) { SDL_Rect rect = SDL_Rect(x * 8, y * 8, 8, 8); - auto back = console[y][x].backColor; auto fore = consoleColor[console[y][x].foreColor]; + auto back = consoleColor[console[y][x].backColor]; + SDL_SetTextureColorMod(t8x8, back >> 16 & 0xFF, back >> 8 & 0xFF, back & 0xFF); + SDL_SetTextureAlphaMod(t8x8, back >> 24 & 0xFF); + SDL_RenderCopy(renderer, t8x8, null, &rect); + /* auto texture = GRPFColor[back].texture; - SDL_RenderCopy(renderer, texture, &fontTable[console[y][x].charater], &rect); + auto back = console[y][x].backColor; + SDL_RenderCopy(renderer, texture, &fontTable[console[y][x].charater], &rect);*/ SDL_SetTextureColorMod(GRPF.texture, fore >> 16 & 0xFF, fore >> 8 & 0xFF, fore & 0xFF); SDL_SetTextureAlphaMod(GRPF.texture, fore >> 24 & 0xFF); SDL_RenderCopy(renderer, GRPF.texture, &fontTable[console[y][x].charater], &rect); diff --git a/SMILEBASIC/token.d b/SMILEBASIC/token.d index 9cd38eb..93a2d27 100644 --- a/SMILEBASIC/token.d +++ b/SMILEBASIC/token.d @@ -58,6 +58,9 @@ enum TokenType WEnd, Inc, Dec, + Data, + Read, + Restore, } struct Token