1
0

Value => TokenValue

This commit is contained in:
otya128
2016-12-17 11:55:07 +09:00
parent 84a82d1336
commit f54b00549e
4 changed files with 164 additions and 28 deletions

View File

@@ -256,6 +256,10 @@ class Compiler
{ {
code ~= new Push(value); code ~= new Push(value);
} }
void genCodeImm(TokenValue value)
{
code ~= new Push(value.toSBImm);
}
void genCodePushGlobal(int ind) void genCodePushGlobal(int ind)
{ {
code ~= new PushG(ind); code ~= new PushG(ind);
@@ -1132,7 +1136,7 @@ class Compiler
{ {
auto data = cast(Data)i; auto data = cast(Data)i;
foreach(j; data.data) foreach(j; data.data)
s.data.addData(j); s.data.addData(j.toSBImm);
} }
break; break;
case NodeType.Read: case NodeType.Read:

View File

@@ -60,8 +60,8 @@ abstract class Expression : Node
} }
class Constant : Expression class Constant : Expression
{ {
Value value; TokenValue value;
this(Value v, SourceLocation loc) this(TokenValue v, SourceLocation loc)
{ {
super.location = loc; super.location = loc;
this.type = NodeType.Constant; this.type = NodeType.Constant;
@@ -515,14 +515,14 @@ class Inc : Statement
} }
class Data : Statement class Data : Statement
{ {
Value[] data; TokenValue[] data;
this(SourceLocation loc) this(SourceLocation loc)
{ {
super.location = loc; super.location = loc;
this.type = NodeType.Data; this.type = NodeType.Data;
this.data = new Value[0]; this.data = new TokenValue[0];
} }
void addData(Value v) void addData(TokenValue v)
{ {
data ~= v; data ~= v;
} }

View File

@@ -168,11 +168,11 @@ class Lexical
num = numstr.to!double; num = numstr.to!double;
if(num <= int.max && num >= int.min && !dot) if(num <= int.max && num >= int.min && !dot)
{ {
token = Token(TokenType.Integer, Value(cast(int)num)); token = Token(TokenType.Integer, TokenValue(cast(int)num));
} }
else else
{ {
token = Token(TokenType.Integer, Value(num)); token = Token(TokenType.Integer, TokenValue(num));
} }
break; break;
} }
@@ -199,17 +199,17 @@ class Lexical
//TRUE/FALSEは3.1でもDATAに使える定数 //TRUE/FALSEは3.1でもDATAに使える定数
if(r == TokenType.True) if(r == TokenType.True)
{ {
token = Token(TokenType.Integer, Value(1)); token = Token(TokenType.Integer, TokenValue(1));
break; break;
} }
if(r == TokenType.False) if(r == TokenType.False)
{ {
token = Token(TokenType.Integer, Value(0)); token = Token(TokenType.Integer, TokenValue(0));
break; break;
} }
if(r != TokenType.Unknown) if(r != TokenType.Unknown)
{ {
token = Token(r, Value(iden)); token = Token(r, TokenValue(iden));
break; break;
} }
} }
@@ -226,7 +226,7 @@ class Lexical
} }
else else
{ {
token = Token(TokenType.Iden, Value(iden)); token = Token(TokenType.Iden, TokenValue(iden));
break; break;
} }
} }
@@ -245,7 +245,7 @@ class Lexical
} }
str ~= c; str ~= c;
} }
token = Token(TokenType.String, Value(str)); token = Token(TokenType.String, TokenValue(str));
break; break;
} }
if(c == '@' || c == '#') if(c == '@' || c == '#')
@@ -267,11 +267,11 @@ class Lexical
} }
if (isLabel) if (isLabel)
{ {
token = Token(TokenType.Label, Value(iden)); token = Token(TokenType.Label, TokenValue(iden));
} }
else else
{ {
token = Token(TokenType.Constant, Value(std.uni.toUpper(iden))); token = Token(TokenType.Constant, TokenValue(std.uni.toUpper(iden)));
} }
break; break;
} }
@@ -327,7 +327,7 @@ class Lexical
} }
wstring numstr = code[start..i]; wstring numstr = code[start..i];
int num = numstr.to!uint(16); int num = numstr.to!uint(16);
token = Token(TokenType.Integer, Value(num)); token = Token(TokenType.Integer, TokenValue(num));
break; break;
} }
if(code[i + 1].toUpper == 'B') if(code[i + 1].toUpper == 'B')
@@ -344,7 +344,7 @@ class Lexical
} }
wstring numstr = code[start..i]; wstring numstr = code[start..i];
int num = numstr.to!uint(2); int num = numstr.to!uint(2);
token = Token(TokenType.Integer, Value(num)); token = Token(TokenType.Integer, TokenValue(num));
break; break;
} }
if(code[i + 1] == '&') if(code[i + 1] == '&')
@@ -1324,11 +1324,11 @@ class Parser
} }
else else
{ {
expr = new Constant(Value(1), lex.location); expr = new Constant(TokenValue(1), lex.location);
} }
if(dec) if(dec)
{ {
expr = new BinaryOperator(new Constant(Value(0), lex.location), TokenType.Minus, expr, lex.location); expr = new BinaryOperator(new Constant(TokenValue(0), lex.location), TokenType.Minus, expr, lex.location);
} }
return new Inc(var, expr, lex.location); return new Inc(var, expr, lex.location);
} }
@@ -1482,7 +1482,7 @@ class Parser
else else
{ {
//とりあえず //とりあえず
step = new Constant(Value(1), lex.location); step = new Constant(TokenValue(1), lex.location);
} }
token = lex.front(); token = lex.front();
Statements statements = forStatements(); Statements statements = forStatements();
@@ -1712,7 +1712,7 @@ class Parser
return print; return print;
} }
//compilerでやるべきな気がする //compilerでやるべきな気がする
bool constcalc(Value left, Value right, TokenType type, out double result) bool constcalc(TokenValue left, TokenValue right, TokenType type, out double result)
{ {
switch (type) switch (type)
{ {
@@ -1797,7 +1797,7 @@ class Parser
{ {
if (constcalc(leftconst.value, rightconst.value, op.operator, result)) if (constcalc(leftconst.value, rightconst.value, op.operator, result))
{ {
auto l = new Constant(Value(result), lex.location); auto l = new Constant(TokenValue(result), lex.location);
constexpr = true; constexpr = true;
if(order != getOPRank(token.type)) if(order != getOPRank(token.type))
return l; return l;
@@ -1898,14 +1898,14 @@ class Parser
lex.popFront(); lex.popFront();
auto a = term(2/*array*/, null); auto a = term(2/*array*/, null);
double result; double result;
if (a.type == NodeType.Constant && constcalc(Value(0), (cast(Constant)a).value, TokenType.Minus, result)) if (a.type == NodeType.Constant && constcalc(TokenValue(0), (cast(Constant)a).value, TokenType.Minus, result))
{ {
node = new Constant(Value(result), lex.location); node = new Constant(TokenValue(result), lex.location);
return node; return node;
} }
else else
{ {
node = new BinaryOperator(new Constant(Value(0), lex.location), TokenType.Minus, a, lex.location); node = new BinaryOperator(new Constant(TokenValue(0), lex.location), TokenType.Minus, a, lex.location);
return node; return node;
} }
} }
@@ -1918,7 +1918,7 @@ class Parser
{ {
if (token.value.castString in constant) if (token.value.castString in constant)
{ {
node = new Constant(Value(constant[token.value.castString]), lex.location); node = new Constant(TokenValue(constant[token.value.castString]), lex.location);
} }
else else
{ {

View File

@@ -1,5 +1,6 @@
module otya.smilebasic.token; module otya.smilebasic.token;
import otya.smilebasic.type; import otya.smilebasic.type;
import std.exception;
enum TokenType enum TokenType
{ {
Unknown, Unknown,
@@ -77,11 +78,142 @@ enum TokenType
Constant, Constant,
} }
enum TokenValueType
{
integer,
double_,
string_
}
struct TokenValue
{
TokenValueType type;
private union
{
int integer;
wstring string_;
double double_;
}
ref integerValue()
{
enforce(type == TokenValueType.integer);
return integer;
}
int integerValue(int val)
{
enforce(type == TokenValueType.integer);
return integer = val;
}
ref stringValue()
{
enforce(type == TokenValueType.string_);
return string_;
}
wstring stringValue(wstring val)
{
enforce(type == TokenValueType.string_);
return string_ = val;
}
ref doubleValue()
{
enforce(type == TokenValueType.double_);
return double_;
}
double doubleValue(double val)
{
enforce(type == TokenValueType.double_);
return double_ = val;
}
int castInteger()
{
switch (type)
{
case TokenValueType.integer:
return integer;
case TokenValueType.double_:
return cast(int)double_;
default:
assert(false);
}
}
double castDouble()
{
switch (type)
{
case TokenValueType.integer:
return integer;
case TokenValueType.double_:
return double_;
default:
assert(false);
}
}
wstring castString()
{
switch (type)
{
case TokenValueType.string_:
return string_;
default:
assert(false);
}
}
bool isNumber()
{
switch (type)
{
case TokenValueType.integer:
case TokenValueType.double_:
return true;
default:
return false;
}
}
bool isString()
{
switch (type)
{
case TokenValueType.string_:
return true;
default:
return false;
}
}
this(int v)
{
type = TokenValueType.integer;
integer = v;
}
this(wstring v)
{
type = TokenValueType.string_;
string_ = v;
}
this(double v)
{
type = TokenValueType.double_;
double_ = v;
}
Value toSBImm()
{
switch (type)
{
case TokenValueType.integer:
return Value(integer);
case TokenValueType.string_:
return Value(string_);
case TokenValueType.double_:
return Value(double_);
default:
assert(false);
}
}
}
struct Token struct Token
{ {
TokenType type; TokenType type;
Value value; TokenValue value;
this(TokenType t, Value v) this(TokenType t, TokenValue v)
{ {
type = t; type = t;
value = v; value = v;