From 628b259cafcf33488c280117116bd331781a66fb Mon Sep 17 00:00:00 2001 From: otya128 Date: Sun, 7 Jun 2015 19:33:51 +0900 Subject: [PATCH] =?UTF-8?q?=E5=8D=98=E9=A0=85=E6=BC=94=E7=AE=97=E5=AD=90?= =?UTF-8?q?=E3=82=92=E5=AE=9F=EF=BF=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SMILEBASIC/VM.d | 14 +++++++++++--- SMILEBASIC/compiler.d | 7 +++++++ SMILEBASIC/main.d | 5 +---- SMILEBASIC/node.d | 12 ++++++++++++ SMILEBASIC/parser.d | 7 ++++++- 5 files changed, 37 insertions(+), 8 deletions(-) diff --git a/SMILEBASIC/VM.d b/SMILEBASIC/VM.d index 04eb517..f29a04d 100644 --- a/SMILEBASIC/VM.d +++ b/SMILEBASIC/VM.d @@ -115,6 +115,7 @@ class PrintCode : Code throw new TypeMismatch(); } } + stdout.flush(); } } /* @@ -197,6 +198,7 @@ class Operate : Code vm.pop(r); int ri = r.integerValue; double rd = r.integerValue; + bool numf = r.type == ValueType.Double || r.type == ValueType.Integer; if(r.type == ValueType.Double) { ri = cast(int)r.doubleValue; @@ -206,10 +208,16 @@ class Operate : Code { //単項演算子 case TokenType.Not: - vm.push(Value(~ri)); + if(numf) + vm.push(Value(~ri)); + else + throw new TypeMismatch(); return; case TokenType.LogicalNot: - vm.push(Value(!ri)); + if(numf) + vm.push(Value(!ri)); + else + throw new TypeMismatch(); return; default: break; @@ -256,7 +264,7 @@ class Operate : Code //数値 * 文字列だとエラー case TokenType.Mul: { - wstring delegate(wstring x, wstring y, int num) mul; + wstring delegate(wstring, wstring, int) mul; mul = (x, y, z) => z > 0 ? x ~ mul(x , y, z - 1) : ""; vm.push(Value(mul(ls, ls, cast(int)rd))); } diff --git a/SMILEBASIC/compiler.d b/SMILEBASIC/compiler.d index 3cebc76..0d85654 100644 --- a/SMILEBASIC/compiler.d +++ b/SMILEBASIC/compiler.d @@ -107,6 +107,13 @@ class Compiler genCodeOP(binop.operator); } break; + case NodeType.UnaryOperator: + { + auto una = cast(UnaryOperator)exp; + compileExpression(una.item); + genCodeOP(una.operator); + } + break; case NodeType.Variable: auto var = cast(Variable)exp; genCodePushGlobal(getGlobalVarIndex(var.name)); diff --git a/SMILEBASIC/main.d b/SMILEBASIC/main.d index e360c89..4fae60b 100644 --- a/SMILEBASIC/main.d +++ b/SMILEBASIC/main.d @@ -44,10 +44,7 @@ FOR I=0 TO 100 ENDIF ENDIF NEXT -A$=\"A\" -?A$ -A$=2 -?A$ +?NOT 1,!!\"a\" "); version(none) auto parser = new Parser(readText("FIZZBUZZ.TXT").to!wstring); auto vm = parser.compile(); diff --git a/SMILEBASIC/node.d b/SMILEBASIC/node.d index 8721b95..1443769 100644 --- a/SMILEBASIC/node.d +++ b/SMILEBASIC/node.d @@ -12,6 +12,7 @@ enum NodeType Variable, CallFunction, VoidExpression, + UnaryOperator, Statements, FunctionBody, @@ -64,6 +65,17 @@ class BinaryOperator : Expression this.item2 = i2; } } +class UnaryOperator : Expression +{ + TokenType operator; + Expression item; + this(TokenType o, Expression i) + { + this.type = NodeType.UnaryOperator; + this.operator = o; + this.item = i; + } +} class Variable : Expression { wstring name; diff --git a/SMILEBASIC/parser.d b/SMILEBASIC/parser.d index 2865d63..1b5dd72 100644 --- a/SMILEBASIC/parser.d +++ b/SMILEBASIC/parser.d @@ -747,7 +747,12 @@ class Parser //TODO:UnaryOperatorの実装 //とりあえず0-exprを作成 lex.popFront(); - node = new BinaryOperator(new Constant(Value(0)), TokenType.Minus, expression()); + node = new BinaryOperator(new Constant(Value(0)), TokenType.Minus, factor()); + return node; + case TokenType.LogicalNot: + case TokenType.Not: + lex.popFront(); + node = new UnaryOperator(token.type, factor()); return node; default: return node;