1
0

項がすべて定数の式を実行前に計算を済ませて実行時には1個の定数として扱うようにした

This commit is contained in:
otya128
2016-09-06 00:09:34 +09:00
parent 5b4160f1b7
commit e03ce4c4a7

View File

@@ -1624,6 +1624,50 @@ class Parser
} }
return print; return print;
} }
//compilerでやるべきな気がする
bool constcalc(Value left, Value right, TokenType type, out double result)
{
switch (type)
{
case TokenType.Plus:
result = (left.castDouble + right.castDouble);
return true;
case TokenType.Minus:
result = (left.castDouble - right.castDouble);
return true;
case TokenType.Mul:
result = (left.castDouble * right.castDouble);
return true;
case TokenType.Div:
result = (left.castDouble / right.castDouble);
return true;
case TokenType.IntDiv:
//TODO:範囲外だとOverflow
result = (left.castInteger / right.castInteger);
return true;
case TokenType.Mod:
result = (left.castDouble % right.castDouble);
return true;
case TokenType.And:
result = (left.castInteger & right.castInteger);
return true;
case TokenType.Or:
result = (left.castInteger | right.castInteger);
return true;
case TokenType.Xor:
result = (left.castInteger ^ right.castInteger);
return true;
case TokenType.LeftShift:
result = (left.castInteger << right.castInteger);
return true;
case TokenType.RightShift:
result = (left.castInteger >> right.castInteger);
return true;
default:
result = double.init;
return !true;
}
}
Expression expression() Expression expression()
{ {
Expression node = null; Expression node = null;
@@ -1657,11 +1701,26 @@ class Parser
op.item2 = term(order - 1, node); op.item2 = term(order - 1, node);
} }
token = lex.front(); token = lex.front();
bool constexpr;
Expression op__ = op;
if (op.item1.type == NodeType.Constant && op.item2.type == NodeType.Constant)
{
double result;
if (constcalc((cast(Constant)op.item1).value, (cast(Constant)op.item2).value, op.operator, result))
{
op__ = new Constant(Value(result), lex.location);
constexpr = true;
if(order != getOPRank(token.type))
return op__;
op = new BinaryOperator(op__, lex.location);
continue;
}
}
version(none) version(none)
write(tt, " "); write(tt, " ");
if(order == getOPRank(token.type)) if(order == getOPRank(token.type))
{ {
BinaryOperator op2 = new BinaryOperator(op, lex.location); BinaryOperator op2 = new BinaryOperator(op__, lex.location);
op.item1 = op2; op.item1 = op2;
} }
version(none)stdout.flush(); version(none)stdout.flush();