233 lines
3.9 KiB
D
233 lines
3.9 KiB
D
module otya.smilebasic.token;
|
|
import otya.smilebasic.type;
|
|
import std.exception;
|
|
enum TokenType
|
|
{
|
|
Unknown,
|
|
Integer,
|
|
Double,
|
|
String,
|
|
Plus,
|
|
Minus,
|
|
Mul,
|
|
Div,
|
|
Mod,
|
|
Or,
|
|
And,
|
|
Xor,
|
|
Not,
|
|
Print,
|
|
If,
|
|
LParen,
|
|
RParen,
|
|
Iden,
|
|
Comma,
|
|
Colon,
|
|
Semicolon,
|
|
NewLine,
|
|
Assign,
|
|
Label,
|
|
Goto,
|
|
Then,
|
|
Else,
|
|
Endif,
|
|
For,
|
|
Next,
|
|
Equal,
|
|
NotEqual,
|
|
Less,//<
|
|
Greater,//>
|
|
LessEqual,
|
|
GreaterEqual,
|
|
LeftShift,//<<
|
|
RightShift,//>>
|
|
LogicalNot,//!
|
|
LogicalAnd,//&&
|
|
LogicalOr,//||
|
|
IntDiv,//DIV
|
|
Gosub,
|
|
Return,
|
|
End,
|
|
Break,
|
|
Continue,
|
|
Var,
|
|
LBracket,//[
|
|
RBracket,//]
|
|
Def,
|
|
Out,
|
|
While,
|
|
WEnd,
|
|
Inc,
|
|
Dec,
|
|
Data,
|
|
Read,
|
|
Restore,
|
|
On,
|
|
Input,
|
|
True,
|
|
False,
|
|
Use,
|
|
Exec,
|
|
Call,
|
|
Common,
|
|
Elseif,
|
|
Repeat,
|
|
Until,
|
|
Swap,
|
|
Dim,
|
|
Constant,
|
|
}
|
|
|
|
enum TokenValueType
|
|
{
|
|
none,
|
|
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
|
|
{
|
|
TokenType type;
|
|
TokenValue value;
|
|
this(TokenType t, TokenValue v)
|
|
{
|
|
type = t;
|
|
value = v;
|
|
}
|
|
this(TokenType t)
|
|
{
|
|
type = t;
|
|
}
|
|
}
|
|
struct SourceLocation
|
|
{
|
|
int line;//何行目
|
|
int pos;//何文字目
|
|
int pos2;//全体から何文字目
|
|
}
|