1
0

演算をdouble対応にした

This commit is contained in:
otya128
2015-06-07 19:11:18 +09:00
parent c871927bc3
commit 978a7a6ee7
5 changed files with 139 additions and 26 deletions

View File

@@ -112,7 +112,7 @@ class PrintCode : Code
break; break;
default: default:
//type mismatch //type mismatch
break; throw new TypeMismatch();
} }
} }
} }
@@ -195,6 +195,25 @@ class Operate : Code
Value l; Value l;
Value r; Value r;
vm.pop(r); vm.pop(r);
int ri = r.integerValue;
double rd = r.integerValue;
if(r.type == ValueType.Double)
{
ri = cast(int)r.doubleValue;
rd = r.doubleValue;
}
switch(operator)
{
//単項演算子
case TokenType.Not:
vm.push(Value(~ri));
return;
case TokenType.LogicalNot:
vm.push(Value(!ri));
return;
default:
break;
}
vm.pop(l); vm.pop(l);
if(l.type == ValueType.String) if(l.type == ValueType.String)
{ {
@@ -232,7 +251,6 @@ class Operate : Code
} }
if(r.type == ValueType.Integer || r.type == ValueType.Double) if(r.type == ValueType.Integer || r.type == ValueType.Double)
{ {
double rd = r.integerValue;
switch(operator) switch(operator)
{ {
//数値 * 文字列だとエラー //数値 * 文字列だとエラー
@@ -260,9 +278,12 @@ class Operate : Code
} }
} }
int li = l.integerValue; int li = l.integerValue;
int ri = r.integerValue;
double ld = l.integerValue; double ld = l.integerValue;
double rd = r.integerValue; if(l.type == ValueType.Double)
{
li = cast(int)l.doubleValue;
ld = l.doubleValue;
}
//とりあえずInteger //とりあえずInteger
switch(operator) switch(operator)
{ {
@@ -278,41 +299,58 @@ class Operate : Code
case TokenType.Div: case TokenType.Div:
ld /= rd; ld /= rd;
break; break;
case TokenType.IntDiv:
//TODO:範囲外だとOverflow
vm.push(Value(cast(int)(ld / rd)));
return;
case TokenType.Mod: case TokenType.Mod:
ld %= rd; ld %= rd;
break; break;
case TokenType.And: case TokenType.And:
ld = li & ri; vm.push(Value(li & ri));
break; return;
case TokenType.Or: case TokenType.Or:
ld = li | ri; vm.push(Value(li | ri));
break; return;
case TokenType.LogicalAnd:
vm.push(Value(li && ri));
return;
case TokenType.LogicalOr:
vm.push(Value(li || ri));
return;
case TokenType.Xor: case TokenType.Xor:
ld = li ^ ri; vm.push(Value(li ^ ri));
break; return;
case TokenType.Equal: case TokenType.Equal:
ld = ld == rd; vm.push(Value(li == ri));
break; return;
case TokenType.NotEqual: case TokenType.NotEqual:
ld = ld != rd; vm.push(Value(li != ri));
break; return;
case TokenType.Less: case TokenType.Less:
ld = ld < rd; vm.push(Value(li < ri));
break; return;
case TokenType.LessEqual: case TokenType.LessEqual:
ld = ld <= rd; vm.push(Value(li <= ri));
break; return;
case TokenType.Greater: case TokenType.Greater:
ld = ld > rd; vm.push(Value(li > ri));
break; return;
case TokenType.GreaterEqual: case TokenType.GreaterEqual:
ld = ld >= rd; vm.push(Value(li >= ri));
break; return;
case TokenType.LeftShift:
vm.push(Value(li << ri));
return;
case TokenType.RightShift:
vm.push(Value(li >> ri));
return;
default: default:
writeln("NotImpl: ", operator); writeln("NotImpl: ", operator);
break; break;
} }
l.integerValue = cast(int)ld; l.type = ValueType.Double;
l.doubleValue = ld;
vm.push(l); vm.push(l);
} }
} }

View File

@@ -3,6 +3,7 @@ import otya.smilebasic.node;
import otya.smilebasic.token; import otya.smilebasic.token;
import otya.smilebasic.vm; import otya.smilebasic.vm;
import otya.smilebasic.type; import otya.smilebasic.type;
import otya.smilebasic.error;
import std.stdio; import std.stdio;
class Compiler class Compiler
{ {
@@ -75,6 +76,7 @@ class Compiler
else else
{ {
//error:二重定義 //error:二重定義
throw new DuplicateVariable();
} }
return global; return global;
} }

38
SMILEBASIC/error.d Normal file
View File

@@ -0,0 +1,38 @@
module otya.smilebasic.error;
import std.exception;
import std.string;
class SmileBasicError : Exception
{
int errnum;
int errline;
int errprg;
this(int slot, int line, string message)
{
super(format("%s in %d:%d", message, slot, line));
}
this(int line, string message)
{
super(format("%s in %d", message, line));
}
this(string message)
{
super(message);
}
}
class TypeMismatch : SmileBasicError
{
this()
{
this.errnum = 8;
super("Type mismatch");
}
}
class DuplicateVariable : SmileBasicError
{
this()
{
this.errnum = 18;
super("Duplicate variable");
}
}

View File

@@ -35,6 +35,7 @@ class Lexical
table['='] = TokenType.Assign; table['='] = TokenType.Assign;
table['<'] = TokenType.Less; table['<'] = TokenType.Less;
table['>'] = TokenType.Greater; table['>'] = TokenType.Greater;
table['!'] = TokenType.LogicalNot;
reserved["OR"] = TokenType.Or; reserved["OR"] = TokenType.Or;
reserved["AND"] = TokenType.And; reserved["AND"] = TokenType.And;
reserved["XOR"] = TokenType.Xor; reserved["XOR"] = TokenType.Xor;
@@ -175,6 +176,30 @@ class Lexical
i += 2; i += 2;
break; break;
} }
if(c == '<' && i + 1 < code.length && code[i + 1] == '<')
{
token = Token(TokenType.LeftShift);
i += 2;
break;
}
if(c == '>' && i + 1 < code.length && code[i + 1] == '>')
{
token = Token(TokenType.RightShift);
i += 2;
break;
}
if(c == '&' && i + 1 < code.length && code[i + 1] == '&')
{
token = Token(TokenType.LogicalAnd);
i += 2;
break;
}
if(c == '|' && i + 1 < code.length && code[i + 1] == '|')
{
token = Token(TokenType.LogicalOr);
i += 2;
break;
}
if(table[cast(char)c] == TokenType.Unknown) if(table[cast(char)c] == TokenType.Unknown)
{ {
//error //error
@@ -254,7 +279,9 @@ class Parser
{ {
switch(type) switch(type)
{ {
// return 8;//&&,|| case TokenType.LogicalAnd:
case TokenType.LogicalOr:
return 8;//&&,||
case TokenType.And: case TokenType.And:
case TokenType.Or: case TokenType.Or:
case TokenType.Xor: case TokenType.Xor:
@@ -266,13 +293,15 @@ class Parser
case TokenType.Greater: case TokenType.Greater:
case TokenType.GreaterEqual: case TokenType.GreaterEqual:
return 6;//==,!=,<,<=,>,>= return 6;//==,!=,<,<=,>,>=
case TokenType.LeftShift:
// return 5;//<<,>> case TokenType.RightShift:
return 5;//<<,>>
case TokenType.Plus: case TokenType.Plus:
case TokenType.Minus: case TokenType.Minus:
return 4;//+,-(bin) return 4;//+,-(bin)
case TokenType.Mul: case TokenType.Mul:
case TokenType.Div: case TokenType.Div:
case TokenType.IntDiv:
case TokenType.Mod: case TokenType.Mod:
return 3;//*,/,DIV,MOD return 3;//*,/,DIV,MOD
// return 2;//-,NOT,! // return 2;//-,NOT,!

View File

@@ -38,6 +38,12 @@ enum TokenType
Greater,//> Greater,//>
LessEqual, LessEqual,
GreaterEqual, GreaterEqual,
LeftShift,//<<
RightShift,//>>
LogicalNot,//!
LogicalAnd,//&&
LogicalOr,//||
IntDiv,//DIV
} }
struct Token struct Token